I have a C program that reads from a txt file. The text file contains a list of words, one word per line. What I want to do is get the words from the text file and print them as one sentence/paragraph, however, when I try to print them, they still print one word per line.
I am storing the words in a 2d char array as I read them from the file. What I think is happening is the array copies the newline char from the txt file, is that correct? and if so, how do I add the word into the array without the new line char?
while(fgets(line,20,lineRead)!=NULL)
{
for(j = 0; j < 20;j++)
{
message[k][j]= line[j];
}
printf("%s", message[k]);
}
I tried a few while loops with no success:
while(line[j] != ' ')
while(line[j] != NULL)
while(line[j] != EOF)
while(line[j] != ' \')
I'm learning C so please be specific in my error. I want to understand what I'm doing wrong, not just get an answer.
Thank you!
You could simply change your for loop to be:
for(j = 0; j < 20 && line[j] != '\n';j++)
{
message[k][j]= line[j];
}
if(j < 20)
message[k][j] = '\0';
The fgets functions includes the newline character \n in the buffer you are reading. Just include a conditional statement within your loop to copy all the characters except \n and \r. Something like:
if ( line[j] != '\n' && line[j] != '\r' ) {
/* Copy the character in your new buffer */
}
The newline characters are part of the string, you need to remove them:
#include <string.h>
while(fgets(line,20,lineRead)!=NULL)
{
char* newline_pos = strpbrk (line, "\n\r"); // get first occurance of newline or carriage return
if (newline_pos)
*newline_pos = '\0';
printf("%s ", line);
}
You should do:
while(fgets(line,20,lineRead)!=NULL)
{
strcpy(message[k], line);
if(message[k][strlen(line)-1] == '\n')
message[k][strlen(line)-1] = '\0']
printf("%s", message[k]);
}
What this does is that it copies line into message[k] and then removes the last character if it is a newline character. We are checking the last character because the documentation says "A newline character makes fgets stop reading, but it is considered a valid character by the function and included in the string copied to str." So if newline is present it will be the last character.
Related
I have text file which include thousands of string
but each string split by a space " "
How can i count how many strings there are?
You don't need the strtok() as you only need to count the number of space characters.
while (fgets(line, sizeof line, myfile) != NULL) {
for (size_t i = 0; line[i]; i++) {
if (line[i] == ' ') totalStrings++;
}
}
If you want to consider any whitespace character then you can use isspace() function.
You can read character by character as well without using an array:
int ch;
while ((ch=fgetc(myfile)) != EOF) {
if (ch == ' ') totalStrings++;
}
But I don't see why you want to avoid using an array as it would probably be more efficient (reading more chars at a time rather than reading one byte at a time).
fgets() function will read entire line from file (you need to know maximum possible size of that line. Then, you can use strtok() from ` to parse the string and count the words.
Using fgetc(), you can count the spaces.
Take note that in cases wherein there are spaces at the beginning of the string, those will be counted as well and it is okay if spaces are present on the start of the line. Else, it won't give accurate results as the first string won't be counted because it has no space before it.
To solve that, we need to check first the first character and increment the string counter if it is an alphabet character.
int str_count = 0;
int c;
// first char
if( isalpha(c = fgetc(myfile)) )
str_count++;
else
ungetc(c, myfile);
Then, we loop through the rest of the contents.
Checking if an alphabet character follows a space will verify if there is a next string after the space, else a space at the end of the line will be counted as well, giving an inaccurate result.
do
{
c = fgetc(myfile);
if( c == EOF )
break;
if(isspace(c)) {
if( isalpha(c = fgetc(myfile)) ) {
str_count++;
ungetc(c, myfile);
} else if(c == '\n') { // for multiple newlines
str_count++;
}
}
} while(1);
Tested on a Lorem Ipsum generator of 1500 words:
http://pastebin.com/w6EiSHbx
I'm building an assembly compiler in C, and I need to print only line which contain code (alphanumeric characters).
However my compiler doesn't recognize a string pointed to by fgets() as empty, since it sometimes contains whitespace characters.
How do I make a condition, to only print lines containing alphanumeric characters?
My code looks like this:
while(fgets(Line,256,Inputfile)!=NULL)
{
i=0;
while(Line[i]!='\n')
{
Instruction[i]=Line[i];
i++;
}
printf("%s \n",Instruction);
}
Thanks,
You have to trim the result of the fgets. You can refer to this answer to view an example that shows how to trim an array of characters in C.
I hope this can help you.
Do I understand you right? You want to ignore lines with only whitespaces?
while(fgets(Line,256,Inputfile)!=NULL)
{
i=0;
int flag = 0;
while(Line[i]!='\n')
{
if(Line[i] != ' ' && Line[i] != '\t'){
flag = 1;
}
Instruction[i]=Line[i];
i++;
}
if(flag == 1){
printf("%s \n",Instruction);
}
}
Add a function isLineToIgnore() in which you check whether the line contains any alphanumeric characters or not.
int isLineToIgnore(char* line)
{
for (char* cp = line; *cp != '\0'; ++cp )
{
if ( isalnum(*cp) )
{
// Don't ignore the line if it has at least one
// alphanumeric character
return 0;
}
}
// The line has no alphanumeric characters.
// Ignore it.
return 1;
}
and then call the function.
We have a program that will take a file as input, and then count the lines in that file, but without counting the empty lines.
There is already a post in Stack Overflow with this question, but the answer to that doesn't cover me.
Let's take a simple example.
File:
I am John\n
I am 22 years old\n
I live in England\n
If the last '\n' didn't exist, then the counting would be easy. We actually already had a function that did this here:
/* Reads a file and returns the number of lines in this file. */
uint32_t countLines(FILE *file) {
uint32_t lines = 0;
int32_t c;
while (EOF != (c = fgetc(file))) {
if (c == '\n') {
++lines;
}
}
/* Reset the file pointer to the start of the file */
rewind(file);
return lines;
}
This function, when taking as input the file above, counted 4 lines. But I only want 3 lines.
I tried to fix this in many ways.
First I tried by doing fgets in every line and comparing that line with the string "\0". If a line was just "\0" with nothing else, then I thought that would solve the problem.
I also tried some other solutions but I can't really find any.
What I basically want is to check the last character in the file (excluding '\0') and checking if it is '\n'. If it is, then subtract 1 from the number of lines it previously counted (with the original function). I don't really know how to do this though. Are there any other easier ways to do this?
I would appreciate any type of help.
Thanks.
You can actually very efficiently amend this issue by keeping track of just the last character as well.
This works because empty lines have the property that the previous character must have been an \n.
/* Reads a file and returns the number of lines in this file. */
uint32_t countLines(FILE *file) {
uint32_t lines = 0;
int32_t c;
int32_t last = '\n';
while (EOF != (c = fgetc(file))) {
if (c == '\n' && last != '\n') {
++lines;
}
last = c;
}
/* Reset the file pointer to the start of the file */
rewind(file);
return lines;
}
Here is a slightly better algorithm.
#include <stdio.h>
// Reads a file and returns the number of lines in it, ignoring empty lines
unsigned int countLines(FILE *file)
{
unsigned int lines = 0;
int c = '\0';
int pc = '\n';
while (c = fgetc(file), c != EOF)
{
if (c == '\n' && pc != '\n')
lines++;
pc = c;
}
if (pc != '\n')
lines++;
return lines;
}
Only the first newline in any sequence of newlines is counted, since all but the first newline indicate blank lines.
Note that if the file does not end with a '\n' newline character, any characters encountered (beyond the last newline) are considered a partial last line. This means that reading a file with no newlines at all returns 1.
Reading an empty file will return 0.
Reading a file ending with a single newline will return 1.
(I removed the rewind() since it is not necessary.)
Firstly, detect lines that only consist of whitespace. So let's create a function to do that.
bool stringIsOnlyWhitespace(const char * line) {
int i;
for (i=0; line[i] != '\0'; ++i)
if (!isspace(line[i]))
return false;
return true;
}
Now that we have a test function, let's build a loop around it.
while (fgets(line, sizeof line, fp)) {
if (! (stringIsOnlyWhitespace(line)))
notemptyline++;
}
printf("\n The number of nonempty lines is: %d\n", notemptyline);
Source is Bill Lynch, I've little bit changed.
I think your approach using fgets() is totally fine. Try something like this:
char line[200];
while(fgets(line, 200, file) != NULL) {
if(strlen(line) <= 1) {
lines++;
}
}
If you don't know about the length of the lines in your files, you may want to check if line actually contains a whole line.
Edit:
Of course this depends on how you define what an empty line is. If you define a line with only whitespaces as empty, the above code will not work, because strlen() includes whitespaces.
I am reading from a textfile and there is a pattern. I am currently reading the file with help of tokens. There are many lines and the pattern breaks if there are any spaces or row breaks after the pattern is finished. This is what I have tried so far:
char newLine[10];
strcpy(newLine, "\n");
int stringValue;
....
*readfromfile*
{
...
stringValue = strcmp(token, newLine);
if(stringValue == 0)
{
...
So if there is a new line or blank space after the line I want the if statement to go through. Does anyone know how to solve this? Is it that token doesn't aquire the character, " " and "\n". If so, what can I do to solve it?
Just trim(newline) before calling strcmp(). trim() will remove any blanks at the beginning or the end of the string.
You can found an example in C in this question.
There's another way: if there's blanks at the end of newLine that you don't want to compare by using strcmp(), use strncmp() instead (with the length of token).
As per your comment you are reading buffer first and then want to remove characters then do as below example, (with assumption your buffer size is of 1024)
int RemoveTokens(char *string)
{
char buf[1024] = {0};
int i = 0;
int j = 0;
strncpy(buf, string, 1024);
memset(string, 0x00, 1024);
for (i=0; i<1024; i++)
{
if (' ' != buf[i] && '\n' != buf[i])
{
string[j] = buf[i];
j++;
}
}
}
Hope it will helps you to do it easily. :D
If I do :
int main(){
const int LENGTH_LINE = 100;
char line[LENGTH_LINE];
int len;
FILE* fp = fopen(file.txt,"r");
fgets(line,LENGTH_LINE,fp);
len = strlen(line);
if(line[len-1] == '\n')
printf("I've a line");
//This work if the line have \n , but if the end line of the text dont have \n how can do it?
}
I need to know if I take a whole line with fgets because I got a delimiter.
According to http://en.cppreference.com/w/c/io/fgets
Reads at most count - 1 characters from the given file stream and stores them in str.
Parsing stops if end-of-file occurs or a newline character is found, in which case str will contain that newline character.
So, once fgets returns, there are 3 possibilities
LENGTH_LINE was reached
We got a newline
EOF was reached.
I'm assuming you have a line in cases 2 and 3.
In this case the detection condition is :
line[len-1] == '\n' || feof(fp)
Check for the newline character:
size_t len = 0;
// ... your code using fgets
len = strlen(line);
if ((len > 0) && (line[len - 1] == '\n'))
// your input contains the newline
After the fgets call, your line may not have a newline at the end if:
The character limit was reached before a newline was scanned - in your case this is LENGTH_LINE.
The end-of-file (EOF) was reached before a newline.
There was a read error, but in case of an error consider the contents of line unusable.
You should be looking at the return value from fgets so that you'll be able to handle the EOF: fgets returns NULL upon end-of-file or a read error. You can use feof to check for the end-of-file.
If you check feof, and know that you're at the end of your input with no fgets errors, then even without a newline character on the final line you'll know that you've read the entire line.
If for some reason you must have a newline character terminating each line, you can add it yourself:
// you've checked for EOF and know this is your final line:
len = strlen(line);
if (line[len-1] == '\n')
printf("I've a line");
else if ((len + 1) < LENGTH_LINE)
{
line[len] = '\n';
line[len + 1] = '\0';
}
else
// no room in your line buffer for an add'l character
Use like this
while(fgets(line,LENGTH_LINE,fp)!=EOF)
// your code here
Why not just use fgetc instead? That way you can just keep scanning until you get to the end of the line so you don't have to check if you have it.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char line[100];
int ch, i = 0;
FILE* fp = fopen(file.txt,"r");
while(ch != '\n' || ch != '\r' || ch != EOF) //or ch != delimiter
{
ch = fgetc(fp);
line[i] = ch;
i++;
}
line[i] = '\n';
line[i+1] = 0x00;
return 0;
}
In that example I just look for a new line, return, or EOF character but you can really make it look for anything you like (e.g. your delimiter). So if your delimiter was q you would just do
while(ch != 'q')...