How should I read a specific number of lines in C? Any tips, since I can't seem to find a relevant thread.
I would like to read N lines from a file and N would be argument given by the user.
Up until this point I have been reading files this way: (line by line until NULL)
int main(void) {
char line[50];
FILE *file;
file= fopen("filename.txt", "r");
printf("File includes:\n");
while (fgets(line, 50, file) != NULL) {
printf("%s", line);
}
fclose(file);
return(0);
}
If N is given by the user, you could just make your loop count up to N:
for (int i = 0; i < N && fgets(line, sizeof line, file); ++i) {
fputs(line, stdout);
}
Related
I am trying to read the ints from a CSV file into a 2D-Array.
Here is my code...
FILE* fp = fopen(argv[1], "r");
int counter = 0;
char line[50];
while (fgets(line, 50, fp)) {
counter++;
}
int arry[counter - 1][4];
NUM_ROWS = counter -1;
counter = 0;
//Iterate File Again to Populate 2D Array of PID, Arrival Time, Burst Time, Priority
//File in Format: #,#,#,#
rewind(fp);
//Skip First Line of Var Names
fgets(line, 50, fp);
while(fgets(line, 50, fp)) {
sscanf(line, "%d%d%d%d", &arry[counter][0], &arry[counter][1], &arry[counter][2], &arry[counter][3]);
counter++;
}
However, sscanf() is not reading the line into the array. I am unsure why this is not working
Edit: Here is a picture of the file.
You need to have the scanf format string which reflects the format of the scanned line.
Always check the result of scanf
Example:
int main(void)
{
char line[] = "34543,78765,34566,35456";
int arry[1][4];
int counter = 0;
int result = sscanf(line, "%d,%d,%d,%d", &arry[counter][0], &arry[counter][1], &arry[counter][2], &arry[counter][3]);
printf("result = %d\n", result);
printf("CSV line = `%s`\n", line);
printf("data read: %d, %d, %d, %d\n", arry[counter][0], arry[counter][1], arry[counter][2], arry[counter][3]);
}
https://godbolt.org/z/zs5Y8ff8h
I want to give input as line number and get output as the corresponding text for that line number in a text file.
Sample text file:
Hi this is Stefen
Hi How are you
Example input:
Enter the line number:2
Expected Output:
Hi How are you
My program is:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
fp = fopen("sample.txt", "r");
if (fp == NULL) {
perror("Unable to open the file\n");
exit(1);
}
char buf[256];
while (fgets(buf, sizeof(buf), fp) != NULL) {
printf("%s\n", buf);
print("~~~~\n");
}
fclose(fp);
return 0;
}
Output I got:(The entire file with the separator ~~~~ below each line)
Hi this is Stefen
~~~~
Hi How are you
~~~~
Can anyone please tell me how to do this?
As pmg suggests, would you please try the following:
#include <stdio.h>
#include <stdlib.h>
#define INFILE "sample.txt"
int main()
{
FILE *fp;
char buf[BUFSIZ];
int count = 0, n;
fp = fopen(INFILE, "r");
if (fp == NULL) {
perror(INFILE);
exit(1);
}
printf("Enter the line number: ");
fgets(buf, sizeof buf, stdin);
n = (int)strtol(buf, (char **)NULL, 10);
while (fgets(buf, sizeof buf , fp) != NULL){
if (++count == n) {
printf("%s", buf);
break;
}
}
fclose(fp);
return EXIT_SUCCESS;
}
Best to use a second file
check if you're at \n that means new line and increment a variable like "line"
printf(" \n Enter line number of the line to be deleted:");
scanf("%d", &delete_line);
//open new file in write mode
ptr2 = fopen("c:\\CTEMP\\newfile.txt", "w");
if(ptr2==NULL)
printf("second error opening newfile");
while (!feof(ptr1))
{
ch = fgetc(ptr1);
if (ch == '\n')
{
temp++;
}
//except the line to be deleted
if (temp != delete_line)
{
//copy all lines in file newfile.c
fputc(ch, ptr2);
}
}
fclose(ptr1);
fclose(ptr2);
"detele_line" variable is for the user to inter.
The easiest way is using array to save the lines, then print the certain line.
#include <stdio.h>
#define M 10010
#define N 256
char buf[M][N];
int main(){
FILE *file;
char fileName[50] = "sample.txt";
file = fopen(fileName, "r");
if(file == NULL)
return 1;
int n = 0;
while(fgets(buf[n], N, file) != NULL){
n++;
}
fclose(file);
int i, x;
printf("Example input:\nEnter the line number:");
scanf("%d", &x);
printf("Expected Output:\n%s", buf[x-1]);
return 0;
}
currently, I am writing code in c program for printing small portion of contents from the input file. Actually, in my code I can able to print just one single line. but, i have to print next 5 lines after that one line.
I am new to programming, please help to solve this problem**
code is given below
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int lineNumber = 2;
int main()
{
FILE *file;
char line[100];
int count = 0;
///Open LS-dyna file to read
file = fopen("P:\\tut_c\\read\\df-read\\in.txt", "r");
if (file == NULL)
{
perror("fopen");
exit(EXIT_FAILURE);
}
else if ( file != NULL )
{
char line[256];
while (fgets(line, sizeof line, file) != NULL)
{
if (count == lineNumber)
{
printf("\n str %s ", line);
fclose(file);
return 0;
}
else
{
count++;
}
}
fclose(file);
}
return 0;
}
The first logical error occurs in your while loop, first iteration, when you close the file and return 0.
Next, there is no reason to have a counter for your lines, since there are many c functions that can handle finding the end of file (eof).
Instead:
Use a while loop for iteration through the file.
Use a standard library c function for file reading.
Check if file has reached the end.
If the line is still valid, then print the line.
Here is some code to reiterate:
int main()
{
FILE *file;
file = fopen("file.txt", "r");
if (!file){ // check if file exists
perror("fopen");
exit(EXIT_FAILURE);
}
else { // if file exists, then...
char line[256];
while(fgets(line, sizeof line, file)){
printf("\n str %s ", line);
}
fclose(file);
}
return 0;
}// end main
Supposing that I have two files like this:
file1.txt
john
is
the new
guy
file2.txt
man
the old
is
rick
cat
dog
I'd like to compare first line from file1 with all the lines from file2 and verify if it exist. If not, go two the second line from file1 and compare it with all the lines from file2.. and so on until eof is reached by file1.
The output that I expect is:
john
the new
guy
How I thought this should be done:
read file1 and file2
create a function which returns the line number of each of them
take the first line from file1 and compare it to all the lines from file2
do this until all the lines from file1 are wasted
Now, I don't know what I'm doing wrong, but I don't get the result that I expect:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int countlines(char *filename)
{
int ch = 0, lines = 0;
FILE *fp = fopen(filename, "r");
if (fp == NULL)
return 0;
do {
ch = fgetc(fp);
if (ch == '\n')
lines++;
} while (ch != EOF);
if (ch != '\n' && lines != 0)
lines++;
fclose(fp);
return lines;
}
int main(int argc, char *argv[])
{
FILE *template_file = fopen(argv[1], "r");
FILE *data_file = fopen(argv[2], "r");
char buffer_line_template_file[100];
char buffer_line_data_file[100];
if (argc != 3)
{
perror("You didn't insert all the arguments!\n\n");
exit(EXIT_FAILURE);
}
if (template_file == NULL || data_file == NULL)
{
perror("Error while opening the file!\n\n");
exit(EXIT_FAILURE);
}
int counter = 0;
for (int i = 0; i < countlines(argv[1]); i++)
{
fgets(buffer_line_template_file, 100, template_file);
for (int j = 0; j < countlines(argv[2]); j++)
{
fgets(buffer_line_data_file, 100, data_file);
if (strcmp(buffer_line_template_file, buffer_line_data_file) != 0)
{
counter++;
printf("%d", counter);
}
}
}
printf("\n\n");
return 0;
}
Could someone please point me into the right direction ? For testing purposes I created a counter at the end which was a part of a small debug. There should be the print() function
As per #chux answer I got the following simplified code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *template_file = fopen(argv[1], "r");
FILE *data_file = fopen(argv[2], "r");
char buffer_line_template_file[100];
char buffer_line_data_file[100];
if (argc != 3)
{
perror("You didn't insert all the arguments!\n\n");
exit(EXIT_FAILURE);
}
if (template_file == NULL || data_file == NULL)
{
perror("Error while opening the file!\n\n");
exit(EXIT_FAILURE);
}
while(fgets(buffer_line_template_file, 100, template_file))
{
buffer_line_template_file[strcspn(buffer_line_template_file, "\n")] = '\0';
rewind(data_file);
while (fgets(buffer_line_data_file, 100, data_file))
{
buffer_line_data_file[strcspn(buffer_line_data_file, "\n")] = '\0';
if (strcmp(buffer_line_template_file, buffer_line_data_file) != 0)
{
printf("%s\n", buffer_line_template_file);
}
}
}
printf("\n\n");
return 0;
}
The above code is giving me the following output, which is not what is expected:
john
john
john
john
john
john
is
is
is
is
is
the new
the new
the new
the new
the new
the new
guy
guy
guy
guy
guy
guy
Problems with OP's code
Imprecise definition of line.
Excessive recalculation
Fuzzy determination of the number of lines in a file.
Unlike string, which has a precise definition in C, reading a line is not so well defined. The primary specificity issue: does a line contain the trailing '\n'. If the first answer is Yes, then does the last text in a file after a '\n' constitute a line? (Excessively long lines are another issue, but let us not deal with that today.)
Thus possibly some lines end with '\n' and others do not, fooling strcmp("dog", "dog\n").
The easiest solution is to read a line until either 1) a '\n' is encountered, 2) EOF occurs or 3) line buffer is full. Then after getting a line, lop off the potential trailing '\n'.
Now all lines code subsequently works with have no '\n'.
fgets(buffer_line_template_file, 100, template_file);
buffer_line_template_file[strcspn(buffer_line_template_file, "\n")] = '\0';
OP's loop is incredible wasteful. Consider a file with 1000 lines. Code will loop, calling 1000 times countlines() (each countlines() call reads 1000 lines) times when one countlines() call would suffice.
// for (int j = 0; j < countlines(argv[2]); j++)
int j_limit = countlines(argv[2]);
for (int j = 0; j < j_limit; j++)
There really is no need to count the line anyways, just continue until EOF (fgets() returns NULL). So no need to fix its fuzzy definition. (fuzzy-ness concerns same issues as #1)
int counter = 0;
for (fgets(buffer_line_template_file, 100, template_file)) {
buffer_line_template_file[strcspn(buffer_line_template_file, "\n")] = '\0';
rewind(data_file);
while ((fgets(buffer_line_data_file, 100, data_file)) {
buffer_line_data_file[strcspn(buffer_line_data_file, "\n")] = '\0';
if (strcmp(buffer_line_template_file, buffer_line_data_file) != 0) {
counter++;
printf("%d", counter);
}
}
}
Other simplifications possible - for another day.
FWIW, following counts lines of text allowing the last line in the file to optionally end with a '\n'.
unsigned long long FileLineCount(FILE *istream) {
unsigned long long LineCount = 0;
rewind(istream);
int previous = '\n';
int ch;
while ((ch = fgetc(inf)) != EOF) {
if (previous == '\n') LineCount++;
previous = ch;
}
return LineCount;
}
Note that this function may get a different result that fgets() calls. Consider a file of one line of 150 characters. fgets(..., 100,...) will report 2 lines. FileLineCount() reports 1.
[Edit] Updated code to conform to OP functionality.
int found = 0;
while (fgets(buffer_line_data_file, 100, data_file))
{
buffer_line_data_file[strcspn(buffer_line_data_file, "\n")] = '\0';
if (strcmp(buffer_line_template_file, buffer_line_data_file) == 0)
{
found = 1;
break;
}
}
if (!found) printf("%s\n", buffer_line_template_file);
This program prints the diff of two files file1.txt and file2.txt.
#include<stdio.h>
#include <stdlib.h>
#include <memory.h>
int main() {
FILE *fp1, *fp2;
int ch1, ch2;
char fname1[40], fname2[40];
char *line = NULL;
size_t len = 0;
ssize_t read;
char *line2 = NULL;
size_t len2 = 0;
ssize_t read2;
fp1 = fopen("file1.txt", "r");
fp2 = fopen("file2.txt", "r");
if (fp1 == NULL) {
printf("Cannot open %s for reading ", fname1);
exit(1);
} else if (fp2 == NULL) {
printf("Cannot open %s for reading ", fname2);
exit(1);
} else {
while ((read = getline(&line, &len, fp1)) != -1 && (read2 = getline(&line2, &len2, fp2)) != -1) {
if (!strcmp(line, line2)) {
printf("Retrieved diff on line %zu :\n", read);
printf("%s", line);
}
}
if (ch1 == ch2)
printf("Files are identical \n");
else if (ch1 != ch2)
printf("Files are Not identical \n");
fclose(fp1);
fclose(fp2);
}
return (0);
}
You already have a very good answer (and always will from chux), but here is a slightly different approach to the problem. It uses automatic storage to reading file2 into an array of strings and then compares each line in file1 against every line in file2 to determine whether it is unique. You can easily convert the code to dynamically allocate memory, but for sake of complexity that was omitted:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MAXC = 256, MAXL = 512 };
void file1infile2 (FILE *fp2, FILE *fp1, size_t *n2, size_t *n1);
int main (int argc, char **argv) {
FILE *fp1 = fopen (argc > 1 ? argv[1] : "file1.txt", "r");
FILE *fp2 = fopen (argc > 2 ? argv[2] : "file2.txt", "r");
size_t n1 = 0, n2 = 0;
if (!fp1 || !fp2) {
fprintf (stderr, "error: file open failed.\n");
return 1;
}
printf ("\nunique words in file1, not in file 2.\n\n");
file1infile2 (fp2, fp1, &n2, &n1);
printf ("\nanalyzed %zu lines in file1 against %zu lines in file2.\n\n",
n1, n2);
return 0;
}
void file1infile2 (FILE *fp2, FILE *fp1, size_t *n2, size_t *n1)
{
char buf[MAXC] = "";
char f2buf[MAXL][MAXC] = { "" };
size_t i;
*n1 = *n2 = 0;
while (*n2 < MAXL && fgets (buf, MAXC, fp2)) {
char *np = 0;
if (!(np = strchr (buf, '\n'))) {
fprintf (stderr, "error: line exceeds MAXC chars.\n");
exit (EXIT_FAILURE);
}
*np = 0;
strcpy (f2buf[(*n2)++], buf);
}
while (*n1 < MAXL && fgets (buf, MAXC, fp1)) {
char *np = 0;
if (!(np = strchr (buf, '\n'))) {
fprintf (stderr, "error: line exceeds MAXC chars.\n");
exit (EXIT_FAILURE);
}
*np = 0, (*n1)++;
for (i = 0; i < *n2; i++)
if (!(strcmp (f2buf[i], buf)))
goto matched;
printf (" %s\n", buf);
matched:;
}
}
Look over the code and let me know if you have any questions.
Example Use/Output
$ ./bin/f1inf2 dat/f1 dat/f2
unique words in file1, not in file 2.
john
the new
guy
analyzed 4 lines in file1 against 6 lines in file2.
I'm trying to read the number of a txt file like this:
input=20
output=10
hidden=5
....
I tried with this code:
char line[30];
char values[100][20];
int i = 0;
FILE *fp;
fp = fopen("myFile.txt", "r");
if(fp == NULL)
{
printf("cannot open file\n");
return 0;
}
while(fgets(line, sizeof(line), fp) != NULL)
{
sscanf(line, "%[^=]", values[i])
printf("%s\n", values[i]);
i++;
}
fclose(fp);
But I obtain only the first word and never the number after the =.
I get
input
output
etc
instead of
20
10
5
etc
How can I get the number??
This line
sscanf(line, "%[^=]", values[i]);
means "read everything up to, but not including, the = sign into values[i]".
If you are interested in the numeric part after the equal sign, change the call as follows:
sscanf(line, "%*[^=]=%19s", values[i]);
This format line means "read and ignore (because of the asterisk) everything up to, and including, the equal sign. Then read a string of length of up to 19 characters into values[i]".
Demo.
Don't use sscanf() for that, redeclare values to store the integers like
int values[LARGE_CONSTANT_NUMBER];
and after fgets() just use strchr
char *number;
number = strchr(line, '=');
if (number == NULL)
continue;
number += 1;
values[i] = strtol(number, NULL, 10);
you could also use malloc() and realloc() if you wish, to make the values array dynamic.
Try it if you like
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
char line[100];
int values[100];
int i;
FILE *fp;
size_t maxIntegers;
fp = fopen("myFile.txt", "r");
if (fp == NULL)
{
perror("cannot open file\n");
return 0;
}
i = 0;
maxIntegers = sizeof(values) / sizeof(values[0]);
while ((fgets(line, sizeof(line), fp) != NULL) && (i < maxIntegers))
{
char *number;
number = strchr(line, '=');
if (number == NULL) /* this line does not contain a `=' */
continue;
values[i++] = strtol(number + 1, NULL, 10);
printf("%d\n", values[i - 1]);
}
fclose(fp);
return 0;
}
with this technique you avoid unecessarily storing the number as a string.