Printing the contents of a file using getc and putc - c

I've seen this question has been asked before, but none of the answers seemed to work for my problem.
I am attempting to write a function that will read the contents of a file, and print them. Here is my code;
int main()
{
int c;
fseek(stdin, 0, SEEK_SET);
c = getc(stdin);
while ((c = getchar()) != EOF)
{
putchar(c);
fseek(stdin, 1, SEEK_CUR);
c = getc(stdin);
}
}
When running the code, I pipe in a file using;
./[Program] < [File.txt]
eg.
./FileRead < Hello.txt
However, when I run it, I get a jumble of random letters. Here is an example:
The contents of the file I am piping in:
Hello World!
This is a test file.
I hope this works!
And here is the output:
eood
Tss sfe
Io iwk
Can anyone help me work out what is wrong?

Just to note that the getc() function moves the active file pointer to the next position automatically after reading a character, so the
//fseek(stdin, 0, SEEK_SET);
opens the file and sets the pointer at the first char
//c = getc(stdin);
The
//getc()
gets the next character in line the 'H' and moves
the pointer forward one character
c now == 'H'
while ((c = getchar()) != EOF)
The
//getchar()
seams to be working (not recommended)
when reading from a file try using
//getc(<filepointer>)
c now == 'e' and the filepointer is moved to the
first 'l'.
Then you have
//putchar(c)
which prints the 'e' character
//fseek(stdin, 1, SEEK_CUR);
Moves the *fp ahead one character to the second 'l'
Then you have
// c = getc(stdin);
Read the next character in line which is the second 'l',
move the *fp to the ' ' space, and repeat.
Basically change the code to this:
while ((ch = getch(stdin)) != EOF)
{
putchar(c);
}
The code should work fine.
Note: For streams opened in text mode, fseek and _fseeki64have limited use, because carriage return–linefeed translations can cause fseek and _fseeki64to produce unexpected results. The only fseek and _fseeki64operations guaranteed to work on streams opened in text mode are:
•Seeking with an offset of 0 relative to any of the origin values.
•Seeking from the beginning of the file with an offset value returned from a call to ftell when using fseekor _ftelli64when using_fseeki64.

Related

C program to get first word of each line from a .txt file and print that word onto another .txt file: Kind of works but also prints random letters

So we have this file called dictionary1.txt and it has words with their pronounciation right next to them. What I want to do is to get the first word from each line and print them onto another txt file that the program creates from scratch. My code does it but it also prints random Chinese letters in between English words, I don't know why.
Here's what the ouput file looks like: https://imgur.com/a/pZthP
(Pronounciations are seperated from the actual words in each line with a blankspace in dictionary1.txt)
My code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
char line[100];
int i = 0;
FILE* fp1 = fopen("dictionary1.txt", "r");
FILE* fp2 = fopen("dictionary2.txt", "w");
if (fp1 == NULL || fp2 == NULL){
printf("ERROR");
return -1;
}
while (fgets(line, 100, fp1) != NULL){
while (line[i] != ' '){
fputc(line[i], fp2);
i++;
}
i=0;
fputc('\0', fp2);
}
return 0;
}
I tried fputc('\n', fp2) as well bu t no matter what I couldn't get onto the next line in the file I created from scratch. I also can't get rid of all the random Chinese letters.
EDIT: I figured it out. The .txt file I was working on was saved in Unicode formatting, which didn't work well with my program. I turned it into ANSI and now it works like a charm.
\n is not the right line separator on all operating systems and all editors.
If you are editing your txt files on Notepad, try fputs ("\r\n", fp2);, where \r means carriage return (cursor returns at the first character of the line) and \n new line.
Generally speaking, Windows uses '\r\n' as line separator, the '\n' character is displayed as something else than end line, at least in Notepad. Linux and Mac OS use different line separators. You may also want to try fprintf(fp2, "\n");
Check this out
\n and \r seem to work everywhere. Why is line.separator more portable?
If you don't mind using C++, you could try to create an output stream os and write os << endl
Note that some compilers may automatically convert '\n' into the corresponding operating system end line character/caracther sequence, whereas some may not.
Another thing, change the while loop condition into line[i] != ' ' && line[i] != '\0' and close the file fp2 using fclose.
.txt file was saved using Unicode formatting. I turned it into ANSI and everything was suddenly fixed.

C Code for Deleting a Line

I am a C noob, and I was trying to make a program to delete a specific line. For this, I chose to copy the contents of the source file, skipping the line intended for deletion. In my original code, I wrote:
while(read_char = fgetc(fp) != '\n') //code to move the cursor position to end of line
{
printf("%c",read_char); //temporary code to see the skipped characters
}
which gave me lots of smileys.
In the end I found the code which gave the intended output:
read_char=fgetc(fp);
while(read_char != '\n') //code to move the cursor position to end of line
{
printf("%c",read_char); //temporary code to see the skipped characters
read_char=fgetc(fp);
}
But what is the actual difference between these two codes?
Assignment has lower priority than not-equal, so:
read_char = fgetc(fp) != '\n'
results in read_char getting a 0 or 1, the result of comparing the result of the fgetc() call against '\n'.
You need parentheses:
while((read_char = fgetc(fp)) != '\n')
which will assign the fgetc() result to read_char before comparing with '\n'.

skip to next line of file ignoring content

hi so i have a program where if there is an # at the begining of the first line of the text file it needs to be ignored, how do you jump to the next line of file? ignoring all that there is after the #?
for example:
#1234
5
I want to print 5 and the rest to be ignored.
I only managed to skip the # if there is nothing behind it
while (a == '#' || a == '\r'|| a == '\n') {
fscanf(inp, "%c", &a);
}
As for your previous question, if your want to ignore comment lines with an initial #, it is highly recommended to read the file line by line with fgets() and to handle non comment lines directly while ignoring comment lines.
It is actually non trivial to do it with fscanf because depending on your format lines, the linefeed may or may not have been consumed.
If you are at the start of a line and want to read the next char while ignoring the comment lines, do this:
int c; // Must be int to accommodate for EOF.
while ((c = getc(inp)) == '#') {
while ((c = getc(inp)) != EOF && c != '\n')
continue;
}
// Here c contains the first char from a non comment line or EOF.
Instead of
while (a == '#' || a == '\r'|| a == '\n') {
fscanf(inp,"%c",&a);
}
Try (pseudo code):
If FirstChar == '#'
Loop/scan until '\n'
On nextline here
If you want to use fscanf().
If better performance is needed, work on buffers directly.

Writing One File To Another Produces Incorrect Results

The program opens a file in read mode. It then creates a second file, writes the contents of the first file into the second and deletes the first. It finishes by renaming the second file to the original name.
Here is the output I get.
User:~ ./main
Before
M1
M2
M3
M4
After
1
M2
M4
ÿ User:~
The output should read the same as the first excluding the second line because that is the line I want to delete.
This is the part of the code that copy's the characters.
ch = getc(File1);
while(ch != EOF);
{
ch = getc(File1);
if (ch == '\n')
ln++;
if (ln != LineToDelete)
{
putc(ch, File2);
}
}
Here is The Full Code On Pastebin
There are three problems that I see:
You are throwing away your first input character, because you read a character before entering your loop then immediately read another after entering.
You are not initializing ln. It appears that you got lucky and it was already 0, so you ended up omitting the line with "M3" rather than "M2". However, you're dealing with undefined behaviour here; anything could have happened.
You are printing out the EOF character.
Try something like this:
ln = 1;
while (EOF != (ch = getc(File1))) {
if ('\n' == ch)
++ln;
if (LineToDelete != ln)
putc(ch, File2);
}

Check for carriage return at the end of a file

I have a text file. I have to check to ensure that the file is ending with a Carriage return. If it is not ending with one then I would like to insert one. The file now being of the correct format I can use it for further parsing. It should work in both Windows & Linux environments.
Try something like this (not tested):
FILE *file = fopen(path, "r+");
char c;
fseek(file, -1, SEEK_END);
fread(&c, 1, 1, file);
if (c != '\r') { /* This will work on Win/Linux and also on a Mac */
fseek(file, 0, SEEK_END);
fprintf(path, "\r");
}
fclose(file);
Note: Are you sure you mean 0x0D? In Linux, lines are ended by 0x0A (\n) and in Windows by the combination 0x0D 0x0A (\r\n).
see i have prepare one file
FILE *b = fopen("jigar.txt","w");
fprintf(b,"jigar\r");
fclose(b);
now i have again open that file for checking
b = fopen("jigar.txt","r");
char f;
go to end of file to last
while(fscanf (b, "%c", &f) != EOF);
go 1 byte previous
fseek( b,-1,1);
read that byte
fscanf(b,"%c",&f);
check it
if(f == 13) \\ here instead of 13 you can writr '\r'
printf("\r is detected");
else
write \r to file...
#include <stdio.h>
void main()
{
FILE *file = fopen("me.txt", "r+"); // A simple text file created using vim
char buffer[100] ;
fseek(file, -2, SEEK_END); // Fetches the last 2 characters of the file
fread(buffer,1,2,file); // Read the last 2 characters into a buffer
printf("\n Character is %s",buffer); // Will print the entire contents of the buffer . So if the line ends with a "\n" we can expect a new line to be printed
//Since i am interested to know how the line feeds & Carriage returns are added to the end of the file , i try to print then both . I have run this code under Suse Linux and if i press enter key after the last line in the file i get two "\n" in the output . I confirmed this using GDB . I would like to run in a Windows environment and check how the behavior changes if any .
printf(" --is %c",buffer[1]);
printf(" --is %c",buffer[2]);
if(buffer[1]=='\r' || buffer[2]=='\n')
//take action
else
// take another action
fclose(file);
}

Resources