C - Reading strings from text file into arrays inside a structure - arrays

I am trying to read text from a .txt file into arrays of a structure.
This is my code (I have played around with this a heap so apologies if it seems all over the place):
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <stdbool.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
int main()
{
int i = 1;
int j = 0;
char temp[4];
struct userStruct { // a struct definition for the users;
char pin[5];
char first[26];
char last[26];
};
struct userStruct userList[10]; // an array of struct user to hold 10 users
struct userStruct * users;
users = &userList;
FILE * filePtr;
filePtr = fopen ("users.txt", "r");
if (filePtr != NULL)
{
fscanf(filePtr, "%s %s %s %s", users[i].pin[j], users[i].first[j], users[i].last[j], temp);
if (strcmp(temp, "\n"))
{
i++;
j++;
}
printf("PIN %s| First %s| Last %s|", users[i].pin[j], users[i].first[j], users[i].last[j]);
fclose(filePtr);
}
else
{
printf("Unable to open users.txt");
}
return 0;
}
The users.txt file contains the text:
1234 John Smith
5678 Barry Cool
Many thanks for the help.

You only want 3 conversion specifiers in the scanf. Try
if( 3 == fscanf(filePtr, "%4s %25s %25s", users[i].pin, users[i].first, users[i].last) ){ ...
The printf is also weird. Try:
printf("PIN %s| First %s| Last %s|", users[i].pin, users[i].first, users[i].last);

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().

Passing data from a two-dimensional array to a structure

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct words {
char *mas;
}words;
int main(void) {
FILE *fp=fopen("test.txt", "r");
char str[100];
char arr[100][100];
int k=0;
words_in->mas=malloc(sizeof(char)*sizeof(arr));
char *istr;
printf("\nFile text\n\n");
for (int i = 0; i < 3; i++) {
istr = fgets(str, 100, fp);
printf("%s", istr);
for (char* istr = strtok(str, " .\t\n"); istr; istr = strtok(NULL, " .\t\n")) {
strcpy(arr[k++], istr);
}
}
How do I pass all words written to the two-dimensional array to the structure?
I want my structure to have an array of char pointers, instead of just one pointer. Or a linked list of pointers. Or an array of structs.
And is it possible to somehow dynamically allocate memory for the structure and for arrays?
If you want to prevent two loops and you are ready to sacrifice some memory you can follow this approach
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
typedef struct words {
char **mas;
}words;
int main()
{
FILE *fp=fopen("test.txt", "r");
struct stat statbuf;
fstat(fileno(fp), &statbuf);
long f_size = statbuf.st_size;
words words_in;
words_in.mas = (char**) malloc(sizeof(char*) * f_size); // In worst case each byte is one word.
char fbuf[f_size+1]; // In worst case all bytes form one word ;
long word_count = 0;
while(fscanf(fp,"%s", fbuf) == 1) {
words_in.mas[word_count] = strdup(fbuf);
word_count++;
}
for (long i = 0; i < word_count; i++) {
printf("%s\n",words_in.mas[i]);
}
return 0;
}
INPUT 1
Apple
Bat
Cat
OUTPUT 1
Apple
Bat
Cat
INPUT 2
AppleBatCat
OUTPUT 2
AppleBatCat
INPUT 3
Apple Bat Cat
OUTPUT 3
Apple
Bat
Cat

File IO: Line by Line Comparison In C, Segmentation Fault

I'm really stuck on this problem. I'm trying to write a program in C that will take a file, and check to see if every line is in alphabetical order.
So the text file
apple
banana
grape
grape
orange
The program would print to stdout "Lines are in order". If the lines are out of order it would print say the lines are out of order and print the first pair of lines where that occurs.
The main thing I'm having trouble with is just debugging, I keep getting a segmentation fault and I'm not sure why. I don't think that theres an instance where I'm trying to dereference a null pointer and I don't think there's an instance where I try to assign something with more memory than a pointer can handle so I'm not sure what the issue is.
Below is my code, I'm really new to C so if there is anything obvious or fundamental flaws in my code I'd really appreciate being told so.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(char* argv[],int argc){
char* fileN = argv[1];
FILE* file = fopen(fileN,"r");
if (file == NULL){
perror("Error: Couldn't open file");
exit(1);
}else{
char *line = malloc(101*sizeof(char));
fgets(line,101,file);
char *comp = malloc(101*sizeof(char));
while(line){
fgets(comp,101,file);
if (comp){
if(strcmp(line,comp) > 0){
printf("Lines out of order\n");
printf("%s\n",line);
printf("%s\n",comp);
free(line);
free(comp);
fclose(file);
exit(1);
}
}
line = comp;
}
printf("Lines are ordered\n");
free(line);
free(comp);
fclose(file);
exit(0);
}
}
Thanks for the help everyone, here is a version of the program that works.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc,char* argv[]){
char* fileN = argv[1];
FILE* file = fopen(fileN,"r");
if (file == NULL){
perror("Error: Couldn't open file");
exit(1);
}else{
char line[101], comp[101];
fgets(line,101,file);
int bool = 1;
while(line && bool){
if (fgets(comp,101,file) != NULL){
if(strcmp(line,comp) > 0){
printf("Lines out of order\n");
printf("%s",line);
printf("%s\n",comp);
fclose(file);
exit(1);
}
strncpy(line,comp,100);
}else{
bool = 0;
}
}
printf("Lines are ordered\n");
fclose(file);
exit(0);
}
}
My mistakes were A) forgetting how to properly copy one string over to one another and B) not realizing that fgets would return null if it fails, that's what I needed to use to make sure my loops actually ends.
Tell me, if you need comments.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_LINE 100
int main(int argc, char* argv[]) {
char a[MAX_LINE];
char b[MAX_LINE];
FILE* fd = fopen(argv[1], "r");
if(!fd) {
puts("Error: Couldn't open file");
exit(1);
}
fgets(a, MAX_LINE, fd);
while(fgets(b, MAX_LINE, fd)) {
if(strcmp(a, b) > 0) {
puts("Lines out of order");
printf("a = %s", a);
printf("b = %s", b);
fclose(fd);
exit(1);
}
strcpy(a, b);
}
puts("Lines are ordered");
fclose(fd);
return 0;
}

Reading Text In 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;
}

Search for a record on a binary file

I'm trying to find if a record exists on a binary file by searching for a name.
Seems I'm not doing something right since the return of my "if" no matter the input it's always found when it doesn't exist.
The debugger states "if = A syntax error in expression", I'm not seeing it.
#ifndef DATA_PLAYER_H_INCLUDED
#define DATA_PLAYER_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Player
{
char nome[50];
int pontos;
}Players;
void ViewPont();
void SearchPont();
#endif // DATA_PLAYER_H_INCLUDED
--
#include "DATA_PLAYER.h"
void ViewPont()
{
Players pl;
FILE *fp;
int i, pontos;
fp = fopen("Pontuacoes.dat", "rb+");
while((fread(&pl, sizeof(Players),1, fp)) != 0 )
{
printf("%s %d\n", pl.nome, pl.pontos);
}
fclose(fp);
}
void SearchPont()
{
char nam[50];
char ch;
Players pl;
FILE * fp;
fp = fopen("Pontuacoes.dat","rb+");
printf("\n nome das pont\n");
fflush(stdout);
scanf("%s", nam);
printf("%s", nam);
while((fread(&pl, sizeof(Players),1, fp)) != 0)
{
if((strcmp(pl.nome, nam))==0);
{
printf("\nregisto encontrado\n");
}
}
fclose(fp);
}
Silly me..........
if(strcmp(pl.nome, nam) ==0);
-> ; that little detail....
if(strcmp(pl.nome, nam) ==0)

Resources