Comparing newline doesn't work properly - c

I have the following code in C to make an input file using an existing input file, but without newlines:
int main()
{
int T;
char c;
FILE *fi,*fo;
fi=fopen("Square-practice.in","r");
fo=fopen("Square-practice-a.in","w");
fscanf(fi,"%d",&T);
fprintf(fo,"%d",T);
while(fscanf(fi,"%c",&c)==1){
if(c=='\n') printf("qwert");
else fprintf(fo,"%c",c);
}
return 0;
}
There is no compiling error.
However, the output file is exactly the same as the input file, with the newline included.
"qwert" is printed 8 times (same as the number of newlines in file fi). So why doesn't the "else" work?
The compiler is MinGW.
Both the fi,fo files are here

I think you have '\r\n' instead of '\n'. So try
int main()
{
int T;
char c;
FILE *fi,*fo;
fi=fopen("Square-practice.in","r");
fo=fopen("Square-practice-a.in","w");
fscanf(fi,"%d",&T);
fprintf(fo,"%d",T);
while(fscanf(fi,"%c",&c)==1){
if(c=='\n' || c=='\r') printf("qwert");
else fprintf(fo,"%c",c);
}
return 0;
}

You can also use fgetc() and fputc(). Just skip any \r or \n before passing each char into new file:
Your code with modifications:
int main()
{
int T;
int iChr
char c;
FILE *fi,*fo;
fi=fopen("Square-practice.in","r");
fo=fopen("Square-practice-a.in","w");
//fscanf(fi,"%d",&T);
//fprintf(fo,"%d",T);
iChr = fgetc(fi)
while(iChr != EOF)
{
if((iChr =='\n')||(iChr =='\r')//skipping new file
{
printf("qwert");
}
else fputc(fo);//no \n or \r, put in new file
}
fclose(fi);
fclose(fo);
return 0;
}

I'm running this on my Linux and I'm getting just what I should be getting: the same file without new line characters and "qwert" printed to stdout. If you're getting something else, it must be an issue with CR/LF translation. Try replacing "r" and "w" with "rt" and "wt", respectively.
Two PS comments:
The given program works (with or without "rt") on my gcc 4.7.2 on Linux, provided that line terminators in the input file are converted from CRLF to LF. This is reasonable when you move a text file from Windows to Linux and can be done, e.g., with the fromdos tool.
It is true that the C standard (section 7.19.5.3, p. 271, for ISO C99, or section 7.21.5.3, p. 306, for ISO C2011) does not require "t" for text files (so, conforming implementations need not implement it), but it seems that some implementations work differently.

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.

Discrepancy with fgetc while reading a text file

I´m beginning with C and I´m willing to understand certain conditions.
I have a text file, generated by notepad or direct via shell by echo in a windows os.
When running this the output show extra chars. What I ´m doing wrong? How I can read text files in a secure way char by char?
Using codeblocks with minggw.
file.txt:
TEST
C program
void main()
{
int i;
FILE *fp;
fp = fopen("file.txt","r");
while ((i = fgetc(fp)) != EOF)
{
printf("%c",i);
}
}
Output
 ■T E S T
Your code has issues, but the result is fine.
Your file is likely UTF-8 with a (confusingly enough) byte order mark in the beginning. Your program is (correctly) reading and printing the bytes of the BOM, which then appear in the output as strange characters before the proper text.
Of course, UTF-8 should never need a byte order mark (it's 8-bit bytes!), but that doesn't prevent some less clued-in programs from incuding one. Window's Notepad is the first program on the list of such programs.
UPDATE: I didn't consider the spacing between your letters, which of course indicate 16-bit input. That's your problem right there, then. Your C code is not reading wide characters.
Try this code
void main()
{
int c,i;
FILE *fp;
fp = fopen("file.txt","r");
while ((i = fgetc(fp)) != EOF)
{
printf("%c",i);
}
}'

fopen() always returns NULL

int main()
{
int i;
FILE *list,*file;
char temp[30];
list=fopen("filelist","rb");
while(fgets(temp,30,list)!=NULL)
{
file=fopen(temp,"r");
{
fclose(list);
return 0;
}
This is my code I basically want to open all files in filelist but my fopen call (exept the first one always returns a NULL am i missing something also this is my filelist
file1
file2
file3
file4
also i dont use file extensions and files exist in the same directory wtih executable.
fgets() stores the new-line character into the buffer it is populating so you need to remove it before calling fopen() within the while.
From the linked reference page for fgets():
Reads at most count - 1 characters from the given file stream and stores them in str. The produced character string is always NULL-terminated. Parsing stops if end-of-file occurs or a newline character is found, in which case str will contain that newline character.
Example code to remove the new-line:
char* nl = strrchr(temp, '\n');
if (nl) *nl = 0;
fgets leaves the newline on the end of the string, which you can plainly see if you add the following line afterwards:
printf ("[%s]\n", temp);
You'll see something like:
[file1
]
You need to remove it before use, which you can do this with something like:
size_t sz = strlen (temp);
if (sz > 0)
if (temp[sz-1] == '\n')
temp[sz-1] = '\0';
You can see this effect in action in the following complete program:
#include <stdio.h>
#include <string.h>
int main (void) {
size_t sz;
char temp[30];
printf ("\n> ");
while (fgets (temp, sizeof(temp), stdin) != NULL) {
printf ("before: [%s]\n", temp);
sz = strlen (temp);
if (sz > 0) {
if (temp[sz-1] == '\n') {
temp[sz-1] = '\0';
}
}
printf ("after : [%s]\n", temp);
printf ("\n> ");
}
return 0;
}
It basically uses your exact method to get a line using fgets (but from standard input) and then outputs the result both before and after removal of the trailing newline. A sample run follows:
pax> ./testprog
> hello
before: [hello
]
after : [hello]
> goodbye
before: [goodbye
]
after : [goodbye]
> [CTRL-D]
pax> _
You may also want to look at a few other things in that code segment:
the use of an open brace { at the end of the while loop.
the fact that you're opening the files within the loop and not doing anything with them (including closing them).
the use of "rb" open mode. Usually this is unnecessary, it's certainly unnecessary if you know it's a text file.
you should always check the return codes of functions that can fail (like fopen) before using them.
the canonical form of main in C where no arguments are needed is int main (void).
I'll state my case of which I am still uncertain: I thought my problem was with "fopen", but after trying every single solution, I ran into the extension problem, which I'm facing in Windows 10. It appears that Windows puts ".txt" automatically but, if you put ".txt" as extension, the name becomes ".txt.txt" at the end. So I left the file name with no extension, and put "file.txt" as argument of "fopen", and that was the only way it has worked for me.

weird issue with output to text in C

This error is driving me nuts. Please help. The code compiles in gcc in terminal and in codeblocks IDE. I'm using Linux and C. It compiles and runs but theres no output in the second text file "onlydata.txt".
#include <stdlib.h>
#include <stdio.h>
/* Data Looks Like This...
E1 101223 9.2
E1 120231 8.4
E2 121212 400.2
I need this....
9.2
8.4
*/
struct Data
{
char *specimen;
int date;
double result;
};
int main()
{
char szBuffer[256];
unsigned int iCt=0;
Data* pData=NULL;
FILE* fpIn=NULL;
fpIn=fopen("data.txt","r"); //Open "Data.dat for read "r" access.
if(fpIn) //and loop through data to count lines.
{ //in iCt
while(!feof(fpIn))
{
fgets(szBuffer,256,fpIn);
iCt++;
}
fclose(fpIn);
}
printf("iCt = %d\n\n",iCt); //Allocate a buffer of Data type
pData=(Data*)malloc(iCt*sizeof(Data)); //to hold iCt objects
if(pData)
{
fpIn=fopen("Data.txt","r"); //Open "Data.dat for read "r" access.
if(fpIn) FILE *fp=NULL;
{
iCt=0;
while(!feof(fpIn)) //read data from text file into buffer
{
fscanf(fpIn,"%s%i%f",
&pData[iCt].specimen,
&pData[iCt].date,
&pData[iCt].result);
// printf("%10.2f\t%4.2f\t%f\t%f\t%f\t%u\t%4.2f\n",
// pData[iCt].specimen,
// pData[iCt].date,
// pData[iCt].result,
iCt++;
FILE *np=NULL;
np = fopen("onlydata.txt","w");
if(np)
fprintf (np," ", &pData[iCt].result);
fclose(np);
}
fclose(fpIn);
}
free(pData);
}
getchar();
return 0;
}
Linux filenames are case sensitive. The second fopen() will fail if the file is called "data.txt".
The actual problem you have stems from the following line:
fprintf (np," ", &pData[iCt].result);
It simply outputs a space to the file. I think you forgot a %f.
EDIT Missed the other obvious error noted by Didier Trosset. :)
you need to have specifier in your fprintf for the result, without the specifier it just writes a whitespace into the file
You should open you destination file only once, at the same time you open your source file.
Right now, for every line of the source file, you open the destination, truncate it, and write one line. In the end, you only got a single line (the last one) in your destination file.
Furthermore, your fprintf does only write a single space character: your format string should be "%f" or at least contain one %f. Actually, the parameter &pData[iCt].result is not used.
Note also that this parameter should not be passed by address, but by value: (remove the &).

C file read by line up to a custom delimiter

Is there a function in C to read a file with a custom delimiter like '\n'?
For example: I have:
I did write \n to exemplify in the file is the LF (Line feed, '\n', 0x0A)
this is the firstline\n this is the second line\n
I'd like the file to read by part and split it in two strings:
this is the firstline\n
this is the second line\n
I know fgets I can read up to a num of characters but not by any pattern. In C++ I know there is a method but in C how to do it?
I'll show another example:
I'm reading a file ABC.txt
abc\n
def\n
ghi\n
With the following code:
FILE* fp = fopen("ABC.txt", "rt");
const int lineSz = 300;
char line[lineSz];
char* res = fgets(line, lineSz, fp); // the res is filled with abc\ndef\nghi\n
fclose(fp);
I excpected fgets had to stop on abc\n
But the res is filled with: abc\ndef\nghi\n
SOLVED: The problem is that I was using Notepad++ in WindowsXP (the one I used
I don't know it happens on other windows) saved the file with different
encoding.
The newline on fgets needs the CRLF not just the CR when you type
enter in notepad++
I opened the windows notepad And it worked the fgets reads the string
up to abc\n on the second example.
fgets() will read one line at a time, and does include the newline character in the line output buffer. Here's an example of the common usage.
#include <stdio.h>
#include <string.h>
int main()
{
char buf[1024];
while ( fgets(buf,1024,stdin) )
printf("read a line %lu characters long:\n %s", strlen(buf), buf);
return 0;
}
But since you asked about using a "custom" delimiter... getdelim() allows you to specify a different end-of-line delimiter.

Resources