printing character array garbage - c

#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!;)

Related

C UNIX - read() reads none existing letters

I've got a little problem while experimenting with some C code. I've tried to use read()-Command to read a text out of a file and store the results in a charArray. But when I print the results they're always different from the file.
Here is the code:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
void main() {
int fd = open("file", 2);
char buf[2];
printf("Read elements: %ld\n", read(fd, buf, 2));
printf("%s\n", buf);
close(fd);
}
The file "file" was created in the same directory using the following UNIX commands:
cat > file
Hi
So it contains just the word "Hi". When I run it, I expect it to read 2 bytes from the file (which are 'H' and 'i') and store them at buf[0] and buf[1]. But when I want to print the result, it appears, that there was an issue, because besides the word "Hi" there are several wierd characters printed (indicating a memory reading/writing problem i guess, due to bad buffer size). I've tried to increase the size of the buf-Array and it appears that when i change the size, the wierd characters printed change. The problem is removed when size reaches 32 bytes.
Can someone explain to me in detail why this is happening?
I've understood so far that read() does not read \'0' when it reads something, and that the third parameter of read() indicates the maximum number of bytes to read.
Antoher thing I've noticed while experimenting with the above code is the following: Let's assume one changes the third parameter (maximum bytes to read) of read() to 3, and the size of buf-Array to 512 (overkill i know, but I really wanted to see what will happen). Now read will acutally read a third character (in my case 'e') and store it into the buffer, even tho this third character does not exist.
I've searched for a while now #stackoverflow and I found many similiar cases, but none of them made me understand my problem. If there is any other thread i missed, it would be a pleasure if u could link me to it.
At last: sry for my bad english, it's not my native language.
Clearly you need to make buf 3 bytes long and use the last byte as the null byte (0 or '\0'). That way, when you print the string, your computer doesn't carry on until he finds another 0 !
The way strings (char arrays really) are handled in C is quite straightforward. Indeed, when dealing with strings (most) if not all functions take under the assumption that string parameters are null terminated (puts) or return null terminated strings (strdup).
The point is that, by default the computer can't tell where a string ends unless it is given the strings size each time he processes it. The easiest implementation around this approach was to append after each string a 0 (namely the null byte). That way, the computer just need to iterate over the string's characters and stop when he finds the termination character (other name for null byte).

printing last 5 lines of file in C in Linux

I need to write a program in C, that prints out last five lines of file by using basic functions like open, read, write, close, lseek. My code so far:
int main(int argc, char *argv[]){
int fd1=open(argv[1], O_RDONLY);
char c;
int currPos = lseek(fd1,-2,SEEK_END);
while(currPos != -1){
read(fd1,&c,sizeof(c));
currPos--;
currPos=lseek(fd1,currPos,SEEK_SET);
if (c == '\n'){
}
}
return 0;
}
Can anybody help me? I think I need to store those characters in array and then print it backwards, but I don't know how.
Why not count the number of characters read while reading back to the fifth newline (call that n) and then do a read of n characters? You don't need to store the data, it's already stored in the file.
Inside the if statement you can count how many '\n' characters you encounter from the end of your file. When you encounter the 6th end-of-line, you know you are at the end of the 6-th-from-the-end line (assuming that the last line also contains an end-of-line character at the end) , so you just print from that point to the end of the file.
You do not need to save the characters in an array, since they are already saved in your file.
You can just do (after your while loop):
int i=read(fd1,&c,1);
while(i){
printf("%c",c);
i = read(fd1,&c,1);
}
It may not be the most efficient way to do it, but it should do the trick.
Note: There is no need to write sizeof(c), since c is a char, and chars are always 1 byte long.
Also, you should always check the return value of read, you never know when something goes wrong in your system and your program crashes because of a read gone wrong.

Please Explain this Example C Code

This code comes from K&R. I have read it several times, but it still seems to escape my grasp.
#define BUFSIZE 100
char buf[BUFSIZE];
int bufp = 0;
int getch(void)
{
return(bufp>0)?buf[--bufp]:getchar();
}
int ungetch(int c)
{
if(bufp>=BUFSIZE)
printf("too many characters");
else buf[bufp++]=c;
}
The purpose of these two functions, so K&R says, is to prevent a program from reading too much input. i.e. without this code a function might not be able to determine it has read enough data without first reading too much. But I don't understand how it works.
For example, consider getch().
As far as I can see this is the steps it takes:
check if bufp is greater than 0.
if so then return the char value of buf[--bufp].
else return getchar().
I would like to ask a more specific question, but I literally dont know how this code achieves what it is intended to achieve, so my question is: What is (a) the purpose and (b) the reasoning of this code?
Thanks in advance.
NOTE: For any K&R fans, this code can be found on page 79 (depending on your edition, I suppose)
(a) The purpose of this code is to be able to read a character and then "un-read" it if it turns out you accidentally read a character too many (with a max. of 100 characters to be "un-read"). This is useful in parsers with lookahead.
(b) getch reads from buf if it has contents, indicated by bufp>0. If buf is empty, it calls getchar. Note that it uses buf as a stack: it reads it from right-to-left.
ungetch pushes a character onto the stack buf after doing a check to see if the stack isn't full.
The code is not really for "reading too much input", instead is it so you can put back characters already read.
For example, you read one character with getch, see if it is a letter, put it back with ungetch and read all letters in a loop. This is a way of predicting what the next character will be.
This block of code is intended for use by programs that make decisions based on what they read from the stream. Sometimes such programs need to look at a few character from the stream without actually consuming the input. For example, if your input looks like abcde12xy789 and you must split it into abcde, 12, xy, 789 (i.e. separate groups of consecutive letters from groups of consecutive digits) you do not know that you have reached the end of a group of letters until you see a digit. However, you do not want to consume that digit at the time you see it: all you need is to know that the group of letters is ending; you need a way to "put back" that digit. An ungetch comes in handy in this situation: once you see a digit after a group of letters, you put the digit back by calling ungetch. Your next iteration will pick that digit back up through the same getch mechanism, sparing you the need to preserve the character that you read but did not consume.
1. The other idea also shown here can be also called as a very primitive I/O stack mangement system and gives the implementation of the function getch() and ungetch().
2. To go a step further , suppose you want to design an Operating System , how can you handle the memory which stores all the keystrokes?
This is solved by the above code snippet.An extension of this concept is used in file handling , especially in editing files .In that case instead of using getchar() which is used to take input from Standard input , a file is used as a source of input.
I have a problem with code given in question. Using buffer (in form of stack) in this code is not correct as when getting more than one extra inputs and pushing into stack will have undesired effect in latter processing (getting input from buffer).
This is because when latter processing (getting input) going on ,this buffer (stack) will give extra input in reverse order (means last extra input given first).
Because of LIFO (Last in first out ) property of stack , the buffer in this code must be quene as it will work better in case of more than one extra input.
This mistake in code confused me and finally this buffer must be quene as shown below.
#define BUFSIZE 100
char buf[BUFSIZE];
int bufr = 0;
int buff = 0;
int getch(void)
{
if (bufr ==BUFSIZE)
bufr=0;
return(bufr>=0)?buf[bufr++]:getchar();
}
int ungetch(int c)
{
if(buff>=BUFSIZE && bufr == 0)
printf("too many characters");
else if(buff ==BUFSIZE)
buff=0;
if(buff<=BUFSIZE)
buf[buff++]=c;
}

Printf a buffer of char with length in C

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;

C stdout printf

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.

Resources