I have a weird issue with printing data out. I use printf to print a char* string and then after that print another one. However part of the first string doesn't get printed and when I print the second string the missing part of the first one is prepended to that one. What is happening here?
I'm writting a simple libpcap implimentation. Here is a sample callback function that will produce the same results. I tried removing buffering and adding a putchar('\n') after printing but it didn't help.
void ParseData(u_char* useless, const struct pcap_pkthdr* pkthdr, const u_char* packet){
int packetLen, i;
packetLen = pkthdr->len;
for (i = 0; i < packetLen; i++){
putchar(packet[i]);
}
}
stdio buffers characters. Unless you tell it otherwise, usually it will only actually issue a write when it sees a newline character. If you want a different behavior, you can remedy it with some of these:
After your first printf, call fflush(stdout); to flush the buffer.
Alternatively, call setbuf(stdout, NULL); to disable buffering. Do this before you do any printfs.
Bypass stdio by coding to platform specific APIs like write (POSIX) or WriteFile (Windows). Usually I would recommend against this, especially for something like stdout..
There is a possibility that your first printf is not having a '\n' at the end. In some cases the data might be buffered and printed together when a '\n' is encountered.
But, this is just a guess. Incase if you cannot post code, try the above.
It's called file stream buffering.
You can disable it or change the size of the buffer using setvbuf(). Or just fflush() after every print. However, the stream buffer is (normally) flushed when a line terminator (\n) is present.
I have a similar experience but this has more to do with double byte. I have 2 char* define back to back. I read some char into the first string. Turns out that is was double byte, so the remaining of the string spill over to the second string.
Related
This is a seemingly simple question that I have not been able to answer for far too long:
I am trying to read input from a user in a C program using fgets(). However, I am running into the problem that if the user enters more characters than fgets() is set to read, the next call to read a string from the user automatically reads the remaining characters in the stdin buffer, and this is NOT behavior I want.
I have tried many ways to clear the stdin stream, and while I know something like
while(getchar()!='\n');
will work, this requires the user to hit enter an additional time which is not something I want.
The structure of the code looks something like this:
void read_string(char *s, int width){
fgets(s,width,stdin);
clear_stdin();
.
.
}
while (1){
read_string()
.
.
}
But I cannot get a clear_stdin() function that works desirably. How on earth can I clear the stdin, without having the user needlessly need to hit enter twice?
To achieve what you want — reading and ignoring extra characters up to a newline if the buffer you supplied is over-filled — you need to conditionally read up to the newline, only doing so if there isn't a newline already in the input buffer that was read.
void read_string(char *s, int width)
{
if (fgets(s, width, stdin) != 0)
{
size_t length = strlen(s);
if (length > 0 && s[length-1] != '\n')
{
int c;
while ((c = getchar()) != '\n' && c != EOF)
;
}
/* Use the input data */
}
else
/* Handle EOF or error */
}
The other part of the technique is to make sure that you use a big enough buffer that it is unlikely that anyone will overflow it. Think in terms of char buffer[4096]; as an opening bid; you can increase it if you prefer. That makes it unlikely that anyone will (be able to) type enough data on a single line to overflow the buffer you provide, thus avoiding the problem.
Another option is to use POSIX getline(). It reads a line into allocated space, allocating more space until the data fits (or you run out of memory). It has at least one other major advantage over fgets() — it reports the number of characters in the line it read, which means it is not confused by null bytes ('\0', usually typed as Control-#) in the input. By contrast, you can't tell whether there was any data entered after the first null byte with fgets(); you have to assume that the input stopped at the first null byte.
Note that the simple loop shown in the question (while (getchar() != '\n');) becomes infinite if it encounters EOF before reading a newline.
You cannot clear stdin in a portable way (because no function from <stdio.h> is specified doing that). BTW, stdin can usually be not only a terminal, but also a redirection or a pipe (or even perhaps some socket). Details matter of course (e.g. your operating system and/or running environment).
You could avoid stdio and use operating system specific ways to deal with standard input (e.g. working at the file descriptor level on POSIX systems).
On Linux (specifically) you might read more about the Tty demystified, and code low level code based on such knowledge. See termios(3). Consider using readline(3).
You could use (on Linux at least) getline(3) to read a heap-allocated line buffer.
while ((getchar()) != '\n');
This will not always work...(but on the bright side, the cases in which it doesn't are just as portable as the cases in which it does). But if stdin has not been redirected, the terminal char of the user's input, unless a manual EOF, will usually be a newline. After you extract what you expect, assuming you don't expect the \n, you can drain what's there up until(and including) the '\n', and then iterate anew. As others have suggested, there are higher level interfaces to deal with this minutia more reliably than manual fringe case handling most of the time.
More Details on Challenge and Solutions
This link contains the cardinal sin of "C\C++" in its heading, which doesn't exist as an entity. Rest assured, separate C examples are given, discrete from alternate C++ ones.
I have a small program I'm writing to practice programming in C.
I want it to use the getchar(); function to get input from the user.
I use the following function to prompt for user input, then loop using getchar() to store input in an array:
The function is passed a pointer referencing a struct's member.
getInput(p->firstName); //The function is passed an argument like this one
void getInput(char * array)
{
int c;
while((c=getchar()) != '\n')
*array++ = c;
*array = '\0'; //Null terminate
}
This function is called multiple times, as it is a part of a function that creates a structure, and populates it's array members.
However when the program executes, The first two calls to it work fine, but any subsequent calls to this function will cause every-other call to getchar() to not wait for keyboard input.
After some debugging I traced the bug to be that getchar(); was for some reason reading in the '\n' character instead of waiting for input, the while loop test fails, and the function returns essentially an empty string.
I have done some research and keep finding to use
while(getchar() != '\n');
at the end of the function in order to properly flush stdin, however, this produces undesirable results, as the program will prompt again for more input after I type ENTER. Pressing ENTER again continues the program, but every-other subsequent calls continue to read in this mysterious '\n' character right off the bat, causing the test to fail, and resulting in empty strings whenever it comes time to print the contents of the the structure.
Could anyone explain to me what is going on here? Why does getchar() keep fetching a '\n' even though I supposedly cleared the input buffer? I have tried just placing a getchar(); statement at the beginning and end of the function, tried 'do while' loops, and taken other jabs at it, but I can't seem to figure this out.
The code you have written has several drawbacks. I'll try to explain them as it is unclear where your code is failing (probably outside the function you posted)
First of all, you don't check for EOF in getchar() result value. getchar(3) doesn't return a char precisely to allow to return al possible char values plus an extra one, EOF, to mark the end of file (this can be generated from a terminal by input of Ctrl-D in unix, or Ctrl-Z on windows machines) That case must be explicitly contempled in your code, as you'll convert the result to a char and will lose the extra information you received from the function. Read getchar(3) man page to solve this issue.
Second, you don't check for input of enough characters to fill all the array and overflow it. To the function you pass only a pointer to the beginning of the array, but nothing indicates how far it extends, so you can be overfilling past the end of its bounds, just overwritting memory that was not reserved for input purposes. This normally results in something called U.B. in the literature (Undefined Behaviour) and is something you must care of. This can be solved by passing a counter of valid positions to fill in the array and decrementing it for each valid position filled. And not allowing more input once the buffer has filled up.
On other side, you have a standar function that does exactly that, fgets(3) just reads one string array from an input file, and stores it on the pointer (and size) you pass to it:
char *fgets(char *buffer, size_t buffer_size, FILE *file_descriptor);
You can use it as in:
char buffer[80], *line;
...
while (line = fgets(buffer, sizeof buffer, stdin)) {
/* process one full line of input, with the final \n included */
....
}
/* on EOF, fgets(3) returns NULL, so we shall be here after reading the
* full input file */
#include<sys/stat.h>
#include<stdio.h>
#include<fcntl.h>
#include<sys/types.h>
int main()
{
int n,i=0;
int f1,f2;
char c,strin[100];
f1=open("data",O_RDWR|O_CREAT|O_TRUNC);
while((c=getchar())!='\n')
{
strin[i++]=c;
}
strin[i]='\0';
write(f1,strin,i);
close(f1);
f2=open("data",O_RDONLY);
read(f2,strin,0);
printf("\n%s\n",strin);
close(f2);
return 0;
}
this code works perfectly fine on some machines while it prints out garbage on others, how to make it run correctly on all machines ?
Your call to read() is not actually reading anything. The third argument is the maximum number of bytes to read, and you're passing it 0:
read(f2,strin,0);
You need to pass it the size of your buffer instead, minus one to accommodate a terminating nul byte:
int bytesread = read(f2,strin,99); /* since your buffer is size 100 */
strin[bytesread] = '\0';
The only reason this is ever working is because you don't clear strin between the first time you fill it via getchar() and the second time when you read() into it. So when you see data, it is leftover data from the first time. If you add a:
memset(strin, 0, 100);
to your original code before the read(), you will see that it never prints the data on any machine.
I think this problem is a simple one and that when you use getchar() to get characters till '\n' you are in fact not accounting for
Windows carriage return being \r\n while it is \n in Unix
You will get details in the link below
Does Windows carriage return \r\n consist of two characters or one character?
P.S. I am a newbee here so i apologize before hand if this answer isn't what you were looking for.
The code that you wrote doesn't work fine! The problem is simple! Or you write and then you read also the \x0 at the end of the string or, when you read, you add the \x0 to the end of the read string! :)
Save also the \x0
write(f1,strin,i+1);
Read and add the \x0
i=read(f2,strin,sizeof(strin)-1);
strin[i]=0;
I think the best solution is the second one!;)
We know that stdin is, by default, a buffered input; the proof of that is in usage of any of the mechanisms that "leave data" on stdin, such as scanf():
int main()
{
char c[10] = {'\0'};
scanf("%9s", c);
printf("%s, and left is: %d\n", c, getchar());
return 0;
}
./a.out
hello
hello, and left is 10
10 being newline of course...
I've always been curious, is there any way to "peek" at the stdin buffer without removing whatever may reside there?
EDIT
A better example might be:
scanf("%9[^.]", c);
With an input of "at.ct", now I have "data" (ct\n) left on stdin, not just a newline.
Portably, you can get the next character in the input stream with getchar() and then push it back with ungetc(), which results in a state as if the character wasn't removed from the stream.
The ungetc function pushes the character specified by c (converted to an unsigned char) back onto the input stream pointed to by stream. Pushed-back characters will be returned by subsequent reads on that stream in the reverse order of their pushing.
Only one character of pushback is guaranteed by the standard, but usually, you can push back more.
As mentioned in the other answers resp. the comments there, in practice, you can almost certainly peek at the buffer if you provide your own buffer with setvbuf, although that is not without problems:
If buf is not a null pointer, the array it points to may be used instead of a buffer allocated by the setvbuf function
that leaves the possibility that the provided buffer may not be used at all.
The contents of the array at any time are indeterminate.
that means you have no guarantee that the contents of the buffer reflects the actual input (and it makes using the buffer undefined behaviour if it has automatic storage duration, if we're picky).
However, in practice the principal problem would be finding out where in the buffer the not-yet-consumed part of the buffered input begins and where it ends.
If you want to look at the stdin buffer without changing it, you could tell it to use a another buffer with setbuf, using an array you can access:
char buffer[BUFSIZ];
if (setbuf(stdin, buffer) != 0)
// error
getchar();
printf("%15s\n", buffer);
This let you see something more than ungetc, but I don't think you can go further in a portable way.
Actually this is legal but is not correct for the standard, quoting from it about the setvbuf (setbuf has the same behavior):
The contents of the array at any time are indeterminate.
So this is not what you need if you're looking for complete portability and standard-compliance, but I can't imagine why the buffer should not contain what is expected. However, it seems to work on my computer.
Beware that you have to provide an array of at least BUFSIZ characters to setbuf, and you must not do any I/O operation on the stream before it. If you need more flexibility, take a look at setvbuf.
You could set your own buffer with setvbuf on stdin, and peek there whenever you want.
I have a buffer which I receive through a serial port. When I receive a certain character, I know a full line has arrived, and I want to print it with printf method. But each line has a different length value, and when I just go with:
printf("%s", buffer);
I'm printing the line plus additional chars belonging to the former line (if it was longer than the current one).
I read here that it is possible, at least in C++, to tell how much chars you want to read given a %s, but it has no examples and I don't know how to do it in C. Any help?
I think I have three solutions:
printing char by char with a for loop
using the termination character
or using .*
QUESTION IS: Which one is faster? Because I'm working on a microchip PIC and I want it to happen as fast as possible
You can either add a null character after your termination character, and your printf will work, or you can add a '.*' in your printf statement and provide the length
printf("%.*s",len,buf);
In C++ you would probably use the std::string and the std::cout instead, like this:
std::cout << std::string(buf,len);
If all you want is the fastest speed and no formatting -- then use
fwrite(buf,1,len,stdout);
The string you have is not null-terminated, so, printf (and any other C string function) cannot determine its length, thus it will continue to write the characters it finds there until it stumbles upon a null character that happens to be there.
To solve your problem you can either:
use fwrite over stdout:
fwrite(buffer, buffer_length, 1, stdout);
This works because fwrite is not thought for printing just strings, but any kind of data, so it doesn't look for a terminating null character, but accepts the length of the data to be written as a parameter;
null-terminate your buffer manually before printing:
buffer[buffer_length]=0;
printf("%s", buffer); /* or, slightly more efficient: fputs(buffer, stdout); */
This could be a better idea if you have to do any other string processing over buffer, that will now be null-terminated and so manageable by normal C string processing functions.
Once you've identified the end of the line, you must append a '\0' character to the end of the buffer before sending it to printf.
You can put a NUL (0x0) in the buffer after receiving the last character.
buffer[i] = 0;