how to print formatted output on terminal using C? - c

I have written a code for a Library system in C. And I want to show the output in following manner on terminal on Linux. I tried with "\t" but the output gets disturbed when the string size varies. I want to print it in fixed manner no matter what string size comes.
I want to print output like below-
I tried to print this using "\t" but the format gets disturbed when the string length of book or author gets smaller or larger. Can somebody help me with this??

Print with fixed character size. Here it is 7,11 and 10 for columns. Refer this for more details this
printf("Column1 Column2 Column3\n");
printf("%7d%11s%10d\n", 100, "String1", 9348);
printf("%7d%11s%10d\n", 23, "String2", 214);

use printf like this :
printf("%-25s|\n", "a string");
printf("%-25s|\n", "another string");
(the - in %-25s is use to left-justifies your text)

not a linux user (hope we are talking about monospace output) but my experienceis that tab has usually configurable size so if you format for 6 character length and someone have 4 character tab the result will be bad. The safest is to use spaces. You can use formated output like:
printf("float number: 8.3%f",7.56);
But that is not always a good choice for example sometimes negative sign mess up things ...
I usually handle such formatting my self with use of string variables:
line = ""
item = "single unformated text value"
compute length of item
add missing spaces (before or after) to line or item
add item to line
loop #2 for all items
output line
loop #1 for all lines

Related

Read from array1 write from array2

Just learning some basic Ruby concepts as a beginner. Not really looking for code as such, rather some fundamental principles behind the following question (obviously feel free to express yourself with code if you need to :0)
In a simple redact text exercise, a user enters some text, then enters the word to be redacted, I'm fine with this and can make it work a number of ways.
However...
to deal with the possibility the user could enter upper and/or lower case letters for either the text or redacted word, I would need to create variables .downcase! again no problem there. But what if once the program runs, you want to return the words to their original state?
I thought perhaps you would need to create an array for the original text, where each word has an index within the array, create a corresponding array with the lowercase letters and if a word is NOT redacted, then you would compare the index from the lowercase array and write the corresponding index from the original array... does this sound correct or am I over thinking it, is there an easier way?
Thanks for your help
puts " What is your message"
text1 = gets.chomp
text2 = text1.downcase
puts "What is your secret word"
redact = gets.chomp.downcase!
words = text2.split (" ")
words.each do |x|
if
x == redact
print "REDACTED" + " "
else
print x + " "
end
end
I've added my working code, you can see that I've separated text1 the original from text2 which isn't strictly necessary as it stands, but to maintain the original formatting
Your solution sounds like it could work and as a beginner it may be useful to write a complete solution like that. But don't forget that ruby can do a lot of fun stuff for you.
Lets say we take input into sentence and the string to redact is stored in redact.
We can do something as simple as this:
sentence.gsub(/#{redact}/i, "*" * redact.length)
gsub finds all occurrences of the first argument and replaces it with the second, returning a new string.
First notice that we are using the redacted string as a regular expression for the first arg and the i indicates that it should match case insensitive, as you wanted.
Now the second arg is simply a string of asterisks of equivalent length to the redacted string.
For example if we have the following:
sentence = 'this is My Sentence'
redact = 'my'
puts sentence.gsub(/#{redact}/i, "*" * redact.length)
The above method will print this is ** Sentence.
Just one extra thing to note: this regex will match all occurrences of the string. For example, if redact = 'is', the resulting sentence will be th** ** My Sentence. You can re-write the regex to avoid this if that's not the expected use case.

Indexing in fread(): Is there a way to set the minimum index to be returned?

Context:
I am trying to read a file, and find out what character is where in the section that I am reading. For the grand scheme of this part of the program, I am using pthreads and fread().
Right now, my code looks like this:
excess=( fread( thread_data[i].buffer, 1, 30, f ) );
printf("\n\nSegFault 1 \n\n%s\n\n\n", thread_data[i].buffer);
printf("\n\nSegFault 2 n\n%s\n\n\n", &thread_data[i].buffer[10]);
To put everything into context, the first statement is printing the entire buffer, including leftover garbage is I am not setting up a null-terminator quite yet.
Then, we I call the second printf, I am getting everything from the 10th character in buffer to the last character of buffer. For example:
frist printf: 1234567890 abcdefgh
second printf: abcdefgh
Question:
How do I index buffer such that I can retrieve a single character to play with? If we look at the above example, when I call:
&thread_data[i].buffer[10]
I am expecting to return ' ', that is, a space
You have the indexing mostly right, but the printing wrong. You can reference the char at index 10 in the buffer like so:
thread_data[i].buffer[10]
If you instead take the address of that char, the resulting char * can be used to refer to the C string consisting of the tail of thread_data[i].buffer starting at index 10. So try this:
printf("\n\nSegFault 2 n\n%c\n\n\n", thread_data[i].buffer[10]);
Note the small changes both to the format string and to the argument.

How can I print specific length of output? Like %d to be always 50 spaces out of the line?

So If I have an output like
Hello How are you 500
Halllo 500
And that "500" is always supposed to be there at that specific position no matter what came infront of it what would needed to be put?
I've tried adding things like
printf ("10%d", w.e);
printf ("\t\t%d", w.e);
but the words like "hello how are you" and "hallo" always influence it and move it further along the same line. How can I position the 500 output to always be in one place?
You need to right pad the preceding word i.e. Hello How are you and Halllo. Once its padded then 500 will always start with same position.
You can right pad the string as:
printf("%-30s", "Hello How are you");
printf("%-30s", "Halllo");
This will assign 30 char length to the string. Your number will follow the next.
something like this?
printf("%-50s%d\n", "Hello How are you", 500);
printf("%-50s%d\n", "Halllo", 500);
prints out:
Hello How are you 500
Halllo 500
You can use printf to specify the minimum number of characters that the leading string should occupy, just as you would when formatting a numeric value.
In fact, you can print both in one call to printf (pseudocode):
format_string = "%-30s%5.0d";
leading_text = "hello";
number = 500;
printf(format_string, leading_text, number);
Here's an alternate way to do it that might be more flexible:
printf("%*d\n", 50-printf("Halllo"), 500);

Reading and comparing numbers from txt file C

I am new to C programming, so I am having difficulties with the problem below.
I have a text file inp.txt which contains information like the following:
400;499;FIRST;
500;599;SECOND;
670;679;THIRD;
I need to type a number and my program needs to compare it with numbers from the inp.txt file.
For example, if I type 450, it's between 400 and 499, so I need write to the word FIRST to the file out.txt
I have no idea how to convert a character array to an int.
I think you'll want these general steps in your program (but I'll leave it to you to figure out how you want to do it exactly)
Load each of the ranges and the text "FIRST", "SECOND", etc. from the file inp.txt, into an array, or several arrays, or similar. As I said in the comment above, fscanf might be handy. This page describes how to use it - the page is about C++, but using it in C should be the same http://www.cplusplus.com/reference/clibrary/cstdio/fscanf/. Roughly speaking, the idea is that you give fscanf a format specifier for what you want to extract from a line in a file, and it puts the bits it finds into the variables you specify)
Prompt the user to enter a number.
Look through the array(s) to work out which range the number fits into, and therefore which text to output
Edit: I'll put some more detail in, as asker requested. This is still a kind of skeleton to give you some ideas.
Use the fopen function, something like this (declare a pointer FILE* input_file):
input_file = fopen("c:\\test\\inp.txt", "r") /* "r" opens inp.txt for reading */
Then, it's good to check that the file was successfully opened, by checking if input_file == NULL.
Then use fscanf to read details from one line of the file. Loop through the lines of the file until you've read the whole thing. You give fscanf pointers to the variables you want it to put the information from each line of the file into. (It's a bit like a printf formatting specifier in reverse).
So, you could declare int range_start, range_end, and char range_name[20]. (To make things simple, let's assume that all the words are at most 20 characters long. This might not be a good plan in the long-run though).
while (!feof(input_file)) { /* check for end-of-file */
if(fscanf(input_file, "%d;%d;%s", &range_start, &range_end, range_name) != 3) {
break; /* Something weird happened on this line, so let's give up */
else {
printf("I got the following numbers: %d, %d, %s\n", range_start, range_end, range_name);
}
}
Hopefully that gives you a few ideas. I've tried running this code and it did seem to work. However, worth saying that fscanf has some drawbacks (see e.g. http://mrx.net/c/readfunctions.html), so another approach is to use fgets to get each line (the advantage of fgets is that you get to specify a maximum number of characters to read, so there's no danger of overrunning a string buffer length) and then sscanf to read from the string into your integer variables. I haven't tried this way though.

Using scanf to read in certain amount of characters in C?

I am having trouble accepting input from a text file. My program is supposed to read in a string specified by the user and the length of that string is determined at runtime. It works fine when the user is running the program (manually inputting the values) but when I run my teacher's text file, it runs into an infinite loop.
For this example, it fails when I am taking in 4 characters and his input in his file is "ABCDy". "ABCD" is what I am supposed to be reading in and 'y' is supposed to be used later to know that I should restart the game. Instead when I used scanf to read in "ABCD", it also reads in the 'y'. Is there a way to get around this using scanf, assuming I won't know how long the string should be until runtime?
Normally, you'd use something like "%4c" or "%4s" to read a maximum of 4 characters (the difference is that "%4c" reads the next 4 characters, regardless, while "%4s" skips leading whitespace and stops at a whitespace if there is one).
To specify the length at run-time, however, you have to get a bit trickier since you can't use a string literal with "4" embedded in it. One alternative is to use sprintf to create the string you'll pass to scanf:
char buffer[128];
sprintf(buffer, "%%%dc", max_length);
scanf(buffer, your_string);
I should probably add: with printf you can specify the width or precision of a field dynamically by putting an asterisk (*) in the format string, and passing a variable in the appropriate position to specify the width/precision:
int width = 10;
int precision = 7;
double value = 12.345678910;
printf("%*.*f", width, precision, value);
Given that printf and scanf format strings are quite similar, one might think the same would work with scanf. Unfortunately, this is not the case--with scanf an asterisk in the conversion specification indicates a value that should be scanned, but not converted. That is to say, something that must be present in the input, but its value won't be placed in any variable.
Try
scanf("%4s", str)
You can also use fread, where you can set a read limit:
char string[5]={0};
if( fread(string,(sizeof string)-1,1,stdin) )
printf("\nfull readed: %s",string);
else
puts("error");
You might consider simply looping over calls to getc().

Resources