Reading Text In C - c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 500
int main(){
int JourneyId;
char Date[MAX];
int Hour;
char BusDriver[MAX];
char Departure[MAX];
char Destination[MAX];
int BusCapacity;
FILE * file;
file = fopen( "Journey.txt" , "rt");
if(file){
while (fscanf(file,"%d,%s,%d,%20[^,],%20[^,],%20[^,],%d", &JourneyId,Date,&Hour,BusDriver,Departure,Destination, &BusCapacity) != EOF){
printf("%d,",JourneyId);
printf("%s",BusDriver);
}
}
else{
printf("Error");
}
return 1;
}
I want to read text file and use this code for adding BST.But If I run , Output is infinite loop.How can I read text file ?
Text file which I want to read:
80,15.04.2014,10,Henry Ford,NewYork,Paris,45
40,15.04.2014,11,Nikola Tesla,Londra,NewYork,40

Rather than read a text file using fscanf(), strongly recommend using fgets() and then parsing via sscanf(), strtok(), strtol(), etc. Check all function return values. It is much easier to cope with the unexpected - which is certainly what is happening in OP's case.
Using modified format from #BLUEPIXY
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 500
int main() {
int JourneyId;
char Date[MAX];
int Hour;
char BusDriver[MAX];
char Departure[MAX];
char Destination[MAX];
int BusCapacity;
FILE * file;
file = fopen("Journey.txt", "rt");
if (file) {
char buf[MAX*4 + 20*3 + 6*1 + 3];
while (fgets(buf, sizeof buf, stdin) != NULL) {
int cnt = sscanf(buf, "%d,%499[^,],%d,%499[^,],%499[^,],%499[^,],%d",
&JourneyId, Date, &Hour, BusDriver, Departure, Destination,
&BusCapacity);
if (cnt != 7) {
printf("Unexpected input \"%s\"", buf);
break;
}
printf("%d,", JourneyId);
printf("%s\n", BusDriver);
}
fclose(file); // Be sure to close
} else {
printf("Error opening\n");
}
return 1;
}

As #BLUPIXY indicated, The following functions (tried on SuSE Linux / gcc)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 500
int main(){
int JourneyId;
char Date[MAX];
int Hour;
char BusDriver[MAX];
char Departure[MAX];
char Destination[MAX];
int BusCapacity;
FILE *file;
file = fopen( "Journey.txt" , "rt");
if(file)
{
// while(fscanf(file,"%d,%s,%d,%20[^,],%20[^,],%20[^,],%d", &JourneyId,Date,&Hour,BusDriver,Departure,Destination, &BusCapacity) != EOF){
while(fscanf(file,"%d,%11[^,],%d,%20[^,],%20[^,],%20[^,],%d", &JourneyId,Date,&Hour,BusDriver,Departure,Destination, &BusCapacity) != EOF){
printf("%d,",JourneyId);
printf("%s",BusDriver);
}
}
else
{
printf("Error");
}
return 1;
}

Related

How to read comma-separated csv file with `sscanf()`

I'm attempting to print an array of structures read from a CSV file in Excel. However, only the students' IDs are printed; other information was also printed but some confusing rare characters. Can you please tell me what could be wrong with this code?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct student {
char ID[8];
char name[32];
int score;
} student;
int main(int argc, char *argv[]) {
student student_list[100];
FILE *source = fopen("students.csv", "r");
if (source == NULL) {
perror("Unable to open the source file.");
exit(1);
}
char buffer[1024];
fgets(buffer, sizeof(buffer), source);
int num_student = 0;
while (!feof(source)) {
student *one_student = student_list + num_student;
sscanf(buffer, "%8[^,] %32[^,] %3[^,]",
&one_student->ID, &one_student->name, &one_student->score);
fgets(buffer, sizeof(buffer), source);
num_student++;
}
for (int i = 0; i < num_student; i++) {
printf("ID: %s name: %-9s score: %-3d\n",
student_list[i].ID, student_list[i].name, student_list[i].score);
}
fclose(source);
return 0;
}
This is a sample input file students.csv:
B213350,John Adam Smith,80
B191835,Mary Elizabeth Smith,71
B201304,Yamazaki Fuyumi,95
B201832,Liam,57
B201834,Alfonso Hernández,65
There are multiple problems:
you should not use feof(). Read Why is “while ( !feof (file) )” always wrong?
Use this loop instead:
while (fgets(buffer, sizeof buffer, source)) {
// handle the line
}
the sscanf() format string is incorrect: the character counts are too large and the , are missing. It should be " %7[^,\n], %31[^,\n], %d" and you should check that the return value is 3, the number of successful conversions expected.
you should stop when the student array is full.
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct student {
char ID[8];
char name[32];
int score;
} student;
int main(int argc, char *argv[]) {
student student_list[100];
FILE *source = fopen("students.csv", "r");
if (source == NULL) {
fprintf(stderr, "Cannot open file students.csv: %s\n", strerror(errno));
return 1;
}
char buffer[1024];
int num_student = 0;
while (num_student < 100 && fgets(buffer, sizeof(buffer), source)) {
student *one_student = &student_list[num_student];
if (sscanf(buffer, " %7[^,\n], %31[^,\n], %d",
one_student->ID, one_student->name,
&one_student->score) == 3) {
num_student++;
} else {
printf("invalid CSV line: %s", buffer);
}
}
for (int i = 0; i < num_student; i++) {
printf("ID: %-9s name: %-32s score: %-3d\n",
student_list[i].ID, student_list[i].name,
student_list[i].score);
}
fclose(source);
return 0;
}
Note that this approach to parsing CSV files cannot handle empty fields. Parsing the line with strtok() would not work either because consecutive commas would be handled as a single separator. You need a different approach using strcspn() or strchr().

Selecting random line from array c

So far I have read all my data into an array
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdlib.h>
int main(void) {
int i=0;
char* string[100];
char line[100];
FILE *file;
file = fopen("plates.txt", "r");
while(fgets(line, sizeof line, file)!=NULL) {
printf("%s",line);
string[i]=line;
i++;
}
fclose(file);
return 0;
}
but i want to now select a random line of my array and print it. All lines need to have an equal chance of being selected but they can only be selected once. Im not too sure how to do this...
Thank you in advance
Please be mindful of this line string[i]=line as it makes all the array entries in string that you set all point to the last line read which is not what you want and it's pretty important to understand that.
That said, here's a solution to the problem that assumes we can just store all the lines in memory and on the stack:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAX_LINE_LENGTH 128
#define MAX_LINE_COUNT 1000
int main(int argc, char **argv) {
char lines[MAX_LINE_COUNT][MAX_LINE_LENGTH];
int numLines = 0;
if (argc < 2) {
fprintf(stderr, "missing file name\n");
return EXIT_FAILURE;
}
FILE *fp = fopen(argv[1], "r");
if (fp != NULL) {
while (fgets(lines[numLines++], MAX_LINE_LENGTH, fp)) {
printf("%03d> %s", numLines, lines[numLines-1]);
}
fclose(fp);
srand (time(NULL));
int randomIndex = rand() % numLines;
printf("Selected random line #%d> %s", randomIndex+1, lines[randomIndex]);
} else {
fprintf(stderr, "file '%s' not found\n", argv[1]);
return EXIT_FAILURE;
}
}
And the corresponding output:
➜ ~ gcc random-line.c && ./a.out random-line.c
001> #include <stdio.h>
002> #include <stdlib.h>
003> #include <string.h>
004> #include <time.h>
005>
006> #define MAX_LINE_LENGTH 128
007> #define MAX_LINE_COUNT 1000
008>
009> int main(int argc, char **argv) {
010> char lines[MAX_LINE_COUNT][MAX_LINE_LENGTH];
011> int numLines = 0;
012>
013> if (argc < 2) {
014> fprintf(stderr, "missing file name\n");
015> return EXIT_FAILURE;
016> }
017>
018> FILE *fp = fopen(argv[1], "r");
019> if (fp != NULL) {
020> while (fgets(lines[numLines++], MAX_LINE_LENGTH, fp)) {
021> printf("%03d> %s", numLines, lines[numLines-1]);
022> }
023> fclose(fp);
024> srand (time(NULL));
025> int randomIndex = rand() % numLines;
026> printf("Selected random line #%d> %s", randomIndex+1, lines[randomIndex]);
027> } else {
028> fprintf(stderr, "file '%s' not found\n", argv[1]);
029> return EXIT_FAILURE;
030> }
031> }
Selected random line #2> #include <stdlib.h>

Read from a file and store it in 2d array

I am working on a function that reads from a file (fp) and stores in the words array. I declared MAX_WORD_SIZE as 128, but when I input any file into this function and check with valgrind, it tells me I have an uninitialized value in the line "while(getline(&line,&count,fp)!=-1)" I really don't get it: what is the uninitialised value? My fp file is valid and the word array is also declared well. Thank you in advance.
#include "functions.h"
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int read_file(FILE *fp, char words[][MAX_WORD_SIZE + 1], int size) {
int i=0;int j=0;
size_t count=MAX_WORD_SIZE;
char* line=malloc(MAX_WORD_SIZE);
while(getline(&line,&count,fp)!=-1){
for(;count>0;count--,j++){
sscanf(line,"%c",&words[i][j]);
}
i++;
}
int totalNums = i;
int totalNum = j;
if (i<size){
return 1;
}
fclose(fp);
return 0;
}
This is the function that I called this read_file function:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "functions.h"
int main(int argc, char *argv[]) {
const char* fileName = argv[1];
FILE *fp = fopen(fileName, "r");
if (fp == NULL) {
printf("Invalid input file\n");
return 1;
}
int size = 0;
int validity = fscanf(fp, "%d", &size);
int returnValue = 0;
char words[size][MAX_WORD_SIZE + 1];
if(validity != 1 || size <= 0) {
printf("The first line is not a valid number\n");
return 1;
}
returnValue = read_file(fp, words, size);
if (returnValue == 1) {
fclose(fp);
return 1;
}
return 0;
}

How to read line by line using system call in C

In my program, I can currently read char by char a file with given name "fichier1.txt", but what I'm looking for is to store a line(line char pointer here) and then display it that way :
-ligne 1 : content line 1
-line 2 : content line 2
-ect...
I've tried to store char by char but since it's a pointer and I'm yet that much familiar with pointers I'm not able to store a line and then reuse the pointer to store the char of the next line.
I have to say that it's part of a school projet and I have to use POSIX standard.
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include <pthread.h>
#include<string.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(){
int read_fd, write_fd;
off_t offset = 0;
char lu;
struct stat statFd;
char *fichier = "fichier1.txt";
read_fd = open(fichier,O_RDONLY);
stat(fichier, &statFd);
if(read_fd == -1){
perror("open");
exit(EXIT_FAILURE);
}
int i = 0;
char * line; // variable to store line
while(lseek(read_fd,offset, SEEK_SET) < statFd.st_size)
{
if(read(read_fd, &lu, 1) != -1)
{
printf("%c",lu);
offset++;
} else {
perror("READ\n");
close(read_fd);
close(write_fd);
exit(EXIT_FAILURE);
}
}
return 0;
}
I'd like to use open() function and not fopen()
Since you are able to read character after character from the file, the logic in while loop will be used to store an entire line (up to 199 characters, you can increase it though) at once in an array & then display it:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(void)
{
FILE *fptr=fopen( "fichier1.txt","r");
int i;
char arr[200]; //THIS ARRAY WILL HOLD THE CONTENTS OF A LINE TEMPORARILY UNTIL IT IS PRINTED
int temp_index=0,line_number=1;;
memset(arr,'\0',sizeof(arr));
while((i=getc(fptr))!=EOF)
{
if(i!='\n')
{
arr[temp_index++]=i;
}
if(i=='\n')
{
printf(line %d: %s\n",line_number++,arr);
temp_index=0;
memset(arr,'\0',sizeof(arr));
}
}
return 0;
}
Calling lseek at every iteration may be inefficient and may fail on devices which are incapable of seeking. I would write a program along these lines below if I don't need to store lines.
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
int lc = 0; /* line count */
int c; /* character read */
FILE *fp = fopen("fichier1.txt", "r");
if (fp == NULL) {
perror("fopen");
return EXIT_FAILURE;
}
while ((c = fgetc(fp)) != EOF) {
printf("line %d: ", ++lc);
while (c != '\n' && c != EOF) {
putchar(c);
c = fgetc(fp);
}
putchar('\n');
}
return 0;
}
Or, a program using fgets to read a line at once:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
int main (void)
{
int lc = 0; /* line count */
char buf[4096]; /* buffer to store the line read */
bool newline = true;
FILE *fp = fopen("fichier1.txt", "r");
if (fp == NULL) {
perror("fopen");
return EXIT_FAILURE;
}
while (fgets(buf, sizeof buf, fp) != NULL) {
if (newline)
printf("line %d: ", ++lc);
printf("%s", buf);
newline = strchr(buf, '\n');
}
return 0;
}

File pointers led to core dump. Probably something stupid

Write the program myuniq.c that contains a function void process_file(FILE* f) that reads all input from the given file one line at the time while keeping two consecutive lines in memory, and prints each line to the standard output if it is not equal to the previously read line.
^^This is the assignment i'm working on. My code below is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void process_file(FILE* f);
int main()
{
FILE *fil = fopen("text.txt","r");
process_file(fil);
return 0;
}
void process_file(FILE* f)
{
FILE *fi = f;
char *firstLine = fgets(firstLine, 999, f);
char *secondLine = fgets(secondLine, 999, f);
while (feof(fi))
{
if (firstLine == secondLine)
{
puts(secondLine);
}
else
{
puts(firstLine);
puts(secondLine);
}
firstLine++;
secondLine++;
}
}
It compiled fine...but on every run it says core dumped. I can't see where I went wrong? Any ideas?
You don't check the return value of fopen, you don't allocate any memory for the strings into which you read, you don't continue reading input from the file, you don't correctly check for the end of input.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MY_MAX_LINE 999
void process_file(FILE* f)
{
char firstLine[MY_MAX_LINE + 1];
char secondLine[MY_MAX_LINE + 1];
while (1)
{
if (!fgets(firstLine, sizeof(firstLine), f))
break;
puts(firstLine);
if (!fgets(secondLine, sizeof(secondLine), f))
break;
if (strncmp(firstLine, secondLine, sizeof(firstLine)))
puts(secondLine);
}
if (!feof(f))
perror("Problem reading from file"), exit(1);
}
int main(int argc, char **argv)
{
FILE *f = fopen("text.txt", "r");
if (!f)
perror("text.txt"), exit(1);
process_file(f);
fclose(f);
return 0;
}

Resources