C Input value from .txt to struct - c

I need to scan values from .txt to a structure so I can work further on with my program. I've been trying various methods from the thread and this is the closes I got to a successful build.
I can NOT get the values to be printed out so I can test if they scanned correctly before working my way further into the program.
I have different values in struct:
struct knyga
{
char vardas[10];
char pavadinimas[50];
int metai;
double kaina;
};
and this is my reading function:
void Skaitymas(struct knyga arr_knyga[]){
FILE *fp;
fp = fopen("duomenys.txt", "r");
int skaicius;
int txt;
txt = fgetc(fp);
while((txt = fgetc(fp)) != EOF){
if(txt == '\n') skaicius++;
txt = fgetc(fp);
}
printf("%d", skaicius);
fp = fopen("duomenys.txt", "r");
for(int i = 0; i < skaicius; i++){
fscanf(fp, "%s %s %d %lf", arr_knyga[i].vardas, arr_knyga[i].pavadinimas, &arr_knyga[i].metai, &arr_knyga[i].kaina);
}
fclose(fp);
}
EDIT:
This is the content of my text file:
Onute Knyga 1999 12.12
Petras Knygute 2001 9.99
EDIT 2:
my main function:
int main() {
struct knyga arr_knyga[10];
Skaitymas(arr_knyga);
return 0;
}

You call txt = fgetc(fp); too often. The two occurrences of this line must be removed.
Especially in the loop you have one call to fgetc that is checked for '\n' and a second call that is not checked, so there is a 50%/50% chance that a '\n' is not counted.
You forgot to initialize the counter variable.
The counting would be correct with this version:
void Skaitymas(struct knyga arr_knyga[]){
FILE *fp;
fp = fopen("duomenys.txt", "r");
int skaicius = 0;
int txt;
while((txt = fgetc(fp)) != EOF){
if(txt == '\n') skaicius++;
}
printf("%d", skaicius);
fclose(fp);
}
But it would be better to omit the line-counting and detect the end-of-file condition in the fscanf loop.
void Skaitymas(struct knyga arr_knyga[]){
FILE *fp;
fp = fopen("duomenys.txt", "r");
int skaicius = 0;
int rc;
while(1)
{
rc = fscanf(fp, "%s %s %d %lf", arr_knyga[skaicius].vardas, arr_knyga[skaicius].pavadinimas, &arr_knyga[skaicius].metai, &arr_knyga[skaicius].kaina);
if(rc == 4)
{
skaicius++;
}
else
{
break;
}
}
if(!feof(fp))
{
fprintf(stderr, "error reading file or wrong data after line %d\n", skaicius);
}
else
{
printf("%d", skaicius);
}
fclose(fp);
}

Related

trying to store a text file into an array

i am trying to read from a text file and store it into an array character by character, ive tested it out by trying to print or check the ii count but it doesn't seem to be storing, any help would be muchly appreciated
char *readFile(char* filename)
{
FILE* f;
int ii = 0;
char* file = (char*)malloc(1000*sizeof(char));
char ch = '\0';
f = fopen(filename,"r");
if(f == NULL)
{
printf("Error opening file '%s'.\n", filename);
}
else
{
while ((ch = fgetc(f)) != EOF)
{
printf("%c",ch);
file[ii] = (char) ch;
ii++;
}
}
/* file[ii] = '\0'; setting last character as null*/
printf("\n");
fclose(f);
free(file);
return file;
}
I have commented out the line containing the code to free the character array before returning, which was basically making the pointer invalid. I have also changed the type of the variable "ch" to int as fgetc() returns integer.
#include <stdio.h>
#include <stdlib.h>
char *readFile(char* filename)
{
FILE* f;
int ii = 0;
char* file = (char*)malloc(1000*sizeof(char));
int ch; //changed to int from char.
f = fopen(filename,"r");
if(f == NULL)
{
printf("Error opening file '%s'.\n", filename);
}
else
{
while ((ch = fgetc(f)) != EOF)
{
// printf("%c",ch);
file[ii] = (char) ch;
ii++;
}
}
/* file[ii] = '\0'; setting last character as null*/
printf("\n");
fclose(f);
//free(file); //commented this line out
return file;
}
int main()
{
char *filename = "sample.txt";
char *file_arr = readFile(filename);
printf("%s \n",file_arr);
return 0;
}

How to read a file into an array of structs?

Im trying to read a text file into an array of structs, but when trying to print the array, the struct is empty. The printing function works fine and I think the problem is in getRawData.
struct student
{
char ID[MAXID + 1];
char f_name[FIRST_NAME_LENGTH + 1];
char s_name[LAST_NAME_LENGTH + 1];
int points[MAXROUNDS];
};
//main//
case 'W':
if(save(array, len) == 0);
{
printf("Data saved.\n");
}
break;
case 'O':
if(getRawData(array, len));
{
printf("File read.\n");
}
break;
int save(struct student *h, int num_students)
{
char name[20];
printf("Enter file name: " );
scanf("%s", name); // Read in filename
FILE *output = fopen(name, "w"); // open the file to write
if (!output) {
return -1; // error
}
for (int i = 0; i < num_students; ++i)
{
fprintf(output, "%s %s %s \n", h[i].f_name, h[i].s_name, h[i].ID);
for(int j = 0; j < MAXROUNDS; j++)
{
fprintf(output, "%d\n", h[i].points[j]);
}
printf("Information of student %s %s (%s) written into file %s\n", h[i].s_name, h[i].f_name, h[i].ID, name);
}
fclose(output); // close
return 0;
}
int getRawData(struct student *records)
{
int i;
int nmemb; // amount of structs
char name[20];
printf("Name of the file to be opened: \n");
scanf("%s", name);
FILE *outtput = fopen(name, "r");
int ch=0;
int lines=0;
if (outtput == NULL);
return 0;
lines++;
while(!feof(outtput))
{
ch = fgetc(outtput);
if(ch == '\n')
{
lines++;
}
}
nmemb = lines / 7;
for(i = 0; i < nmemb; i++) {
fscanf(outtput, "%s %s %s", records[i].f_name, records[i].s_name, records[i].ID);
for(int j = 0; j < MAXROUNDS; j++)
{
fscanf(outtput, "%d\n", &records[i].points[j]);
}
}
printf("%d", lines);
return i;
}
So my goal is to get the data from the file and write it over whatever there is stored in the struct array. I would appreciate some help as I have been working on this for way too long.
Look at this code in getRawData(), first you are reading file to identify total number of lines:
while(!feof(outtput))
{
ch = fgetc(outtput);
if(ch == '\n')
.....
.....
due to this the file stream pointer pointing to EOF and after this, in the for loop, you are doing:
for(i = 0; i < nmemb; i++) {
fscanf(outtput, "%s %s %s", records[i].f_name, records[i].s_name, records[i].ID);
.....
.....
Here, the fscanf() must be returning the EOF because there is nothing remain to read from stream file. You should check the return value of fscanf() while reading file.
You should reset the pointer to start of file before reading it again. You can use either rewind(ptr) or fseek(fptr, 0, SEEK_SET). Below is a sample program to show you what is happening in your code and how the solution works:
#include <stdio.h>
int main (void) {
int ch;
int lines = 0;
char str[100];
FILE *fptr = fopen ("file.txt", "r");
if (fptr == NULL) {
fprintf (stderr, "Failed to open file");
return -1;
}
while (!feof(fptr)) {
ch = fgetc (fptr);
if(ch == '\n') {
lines++;
}
}
printf ("Number of lines in file: %d\n", lines);
printf ("ch : %d\n", ch);
printf ("Now try to read file using fscanf()\n");
ch = fscanf (fptr, "%s", str);
printf ("fscanf() return value, ch : %d\n", ch);
printf ("Resetting the file pointer to the start of file\n");
rewind (fptr); // This will reset the pointer to the start of file
printf ("Reading file..\n");
while ((ch = fscanf (fptr, "%s", str)) == 1) {
printf ("%s", str);
}
printf ("\nch : %d\n", ch);
fclose (fptr);
return 0;
}
The content of file reading in the above program:
Hello Vilho..
How are you!
Output:
Number of lines in file: 2
ch : -1
Now try to read file using fscanf()
fscanf() return value, ch : -1
Resetting the file pointer to the start of file
Reading file..
HelloVilho..Howareyou!
ch : -1
Here you can see, the first ch : -1 indicate that the file pointer is at EOF and if you try to read you will get EOF because there is nothing left to read. After resetting file pointer, you can see fscanf() is able to read file.
You should not use while (!feof(file)). Check this.

How do I count the number of characters in a file?

I have copied the contents of a file to another file and I am trying to get the line, word, and character count. The code I have right now displays the number of lines and words in the file content. Now I need to display the character count but I am unsure of how to do that. I am guessing a for loop? But I am not sure.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define MAX_WORD_LEN 100
#define MAX_LINE_LEN 1000
#define ipsumFile "Lorem ipsum.txt"
#define ipsumCopy "Lorem ipsum_COPY.txt"
int wordCount(FILE *fp);
int charCount(FILE *fp);
int sendContentTo(FILE *fp, FILE *out);
int getWordAt(FILE *fp, int pos, char *word);
int appendToFile(char *fileName, char *newText);
int main(void)
{
FILE *fp, *fp2; //"file pointer"
int ch; //place to store each character as read
//open Lorem ipsum.txt for read
if ((fp = fopen(ipsumFile, "r")) == NULL)
{
fprintf(stdout, "Can't open %s file.\n", ipsumFile);
exit(EXIT_FAILURE);
}
//open Lorem ipsumCopy for writing
if ((fp2 = fopen(ipsumCopy, "w+")) == NULL)
{
fprintf(stdout, "Can't open %s file.\n", ipsumCopy);
exit(EXIT_FAILURE);
}
//print out and count all words in Lorem ipsum.txt
int numOfWords = wordCount(fp);
//print out and count all lines in Lorem ipsum.txt
int numOfLines = sendContentTo(fp, stdout);
//copy the content of Lorem ipsum.txt into a new file (ipsumCopy)
numOfLines = sendContentTo(fp, fp2);
fclose(ipsumFile);
fclose(ipsumCopy);
// close Lorem ipsum.txt
if (fclose(fp) != 0)
fprintf(stderr, "Error closing file\n");
if (fclose(fp2) != 0)
fprintf(stderr, "Error closing copy\n");
return 0;
}
int sendContentTo(FILE *in, FILE *out)
{
fprintf(stdout, "Performing file copy...\n\n");
//start at the beginning of the file
rewind(in);
// array to hold one line of text up to 1000 characters
char line[MAX_LINE_LEN];
int lineCount = 0;
// read one line at a time from our input file
while (fgets(line, MAX_LINE_LEN, in) != NULL)
{
//send line we just read to output.
fprintf(out, "%s", line);
//count the lines
lineCount++;
}
fprintf(stdout, "\nFinished line count.\n");
fprintf(stdout, "Count is: %d.\n\n", lineCount);
// Return how many text lines
// we've processed from input file.
return lineCount;
}
// Read content from file one character at a time.
// Returns number of total characters read from the file.
int charCount(FILE *fp)
{
fprintf(stdout, "Performing char count...\n\n");
rewind(fp);
int charCount = 0;
char ch;
//print out each character, and return the
// number of characters in the file.
fprintf(stdout, "\nFinished character count. \n");
fprintf(stdout, "Count is: %d. \n\n", charCount);
return charCount;
}
// Read content from file one word at a time.
// Returns number of total words read from the file.
int wordCount(FILE *fp)
{
fprintf(stdout, "Performing word count...\n\n");
rewind(fp);
char word[MAX_WORD_LEN];
int wordCount = 0;
while (fscanf(fp, "%s", word) == 1)
{
// Send entire word string
// we just read to console
puts(word);
//count the word
wordCount++;
}
fprintf(stdout, "\nFinished word count.\n");
fprintf(stdout, "Count is: %d.\n\n", wordCount);
return wordCount;
}
You don't need to write different function for counting the number of lines, words, and characters in a file. You can do it in a single parsing of file character by character and while parsing, in order to copy the content of file to another file, you can write the characters to another file. You can do:
#include <stdio.h>
#include <stdlib.h>
int count_and_copy(const char * ipsumFile, const char * ipsumCopy)
{
unsigned int cCount = 0, wCount = 0, lCount = 0;
int incr_word_count = 0, c;
FILE *fp, *fp2;
if ((fp = fopen(ipsumFile, "r")) == NULL)
{
fprintf(stdout, "Can't open %s file.\n", ipsumFile);
exit(EXIT_FAILURE);
}
if ((fp2 = fopen(ipsumCopy, "w+")) == NULL)
{
fprintf(stdout, "Can't open %s file.\n", ipsumCopy);
exit(EXIT_FAILURE);
}
while((c = fgetc(fp)) != EOF)
{
fputc(c, fp2); // write character c to the copy file
cCount++; // character count
if(c == '\n') lCount++; // line count
if (c == ' ' || c == '\n' || c == '\t')
incr_word_count = 0;
else if (incr_word_count == 0) {
incr_word_count = 1;
wCount++; // word count
}
}
fclose (fp);
fclose (fp2);
printf ("Number of lines : %u\n", lCount);
printf ("Number of words : %u\n", wCount);
printf ("Number of characters : %u\n", cCount);
return 0;
}
int main()
{
/* Assuming, you want to count number of lines, words
* and characters of file1 and copy the contents of file1
* to file2.
*/
count_and_copy("file1", "file2");
return 0;
}
I suppose that the following approach will work:
void *cw(const char *fname)
{
FILE *f = fopen(fname, "r");
if (f == NULL) {
fprintf(stderr, "fopen(%s): %s\n", fname, strerror(errno));
exit(EXIT_FAILURE);
}
int bc = 0; /* bytes counter */
int wc = 0 ; /* words counter */
int nlc = 0; /* new lines counter */
const int in_word_state = 0;
const int out_word_state = 1;
int state = out_word_state;
int c = 0;
for (;;) {
c = fgetc(f);
if (ferror(f) != 0) {
perror("fgetc");
goto error;
}
if (feof(f))
break;
if (c == '\n')
nlc++;
if (c == ' ' || c == '\t' || c == '\n')
state = out_word_state;
if (state == out_word_state) {
state = in_word_state;
wc++;
}
bc++;
}
if (fclose(f) == EOF) {
perror("fclose");
goto error;
}
printf("w: %d, c: %d, l:%d\n", wc, bc, nlc);
error:
if (f != NULL) {
if (fclose(f) == EOF) {
perror("fclose");
}
}
exit(EXIT_FAILURE);
}

How to code my own version of tail unix command in C language?

I want to write my own code for tail Unix command but I am having a lot of trouble doing that. I am completely new to C language and apparently lost on how to fix my code. I am having number of problems regarding my code:
I am unable to read and print lines from text file in the if statements it is not printing any string from file when I run it don't know why?
Unable to print specific lines in if statement by taking user input as starting line and then printing till the End of File.
I am having trouble figuring out the right solution to my problems and debugging what problems there are in code.
I would really appreciate your help in figuring how to do all the above in my code. If someone can help make changes and get my code to work right.
#include <stdio.h>// for fopen, fscanf, fclose, fprintf
#include <stdlib.h>// for exit
#include <string.h>
int main(int argc, const char * argv[]){
printf("Opening file\n");
char filename[64]; // file attribute
strcpy(filename, argv[1]); //copy string from argv[1] to filename
printf("FILENAME: %s \n", filename);
FILE* fp; // file pointer
int ch, linestotal = 0, user;
char c[10000];
if(argv[2]){ //checking input argv[2]
user = atoi(argv[2]); // char to int
}
fp = fopen( filename, "r"); // file read
if(fp == NULL){ // verify file is opened
printf("Error opening file");
exit(1);
}
while(!feof(fp)) // check end of file
{
ch = fgetc(fp);
if(ch == '\n')
{
linestotal++; //Checking total lines inside file
}
}
printf("Total no. of lines: %d\n", linestotal );
printf("User input: %d\n", user );
printf("**********************\n");
if (!user && linestotal<= 10)
{
while ( (ch = fgetc(fp) ) != EOF)
printf("%c", ch);
fclose(fp);
printf("********************\n");
}if(!user && linestotal>10) { // to print 10 lines
for(int i = (linestotal-10); i <= (linestotal); i++)
{ c[i] = fgetc(fp);
printf("%c", c[i]);
}
fclose(fp);
printf("********************\n");
}if(user && user<linestotal) {
for(int i = (linestotal-user); i <= (linestotal); i++)
{ c[i] = fgetc(fp);
printf("%c", c[i]);
}
fclose(fp);
printf("********************\n");
}if(user && user>linestotal){
while ( (ch = fgetc(fp) ) != EOF)
printf("%c", ch);
fclose(fp);
printf("********************\n");
}else{
printf("Unable to read and print file \n");
}
printf("End of file");
return 0;
}

How to write text from file to a string in C

I want to write code were the user is asked to write the name of a file. Then I want to analyze the file's content for a symbol, let's say 'e'.
My problem is that I don't know how to start analyzing the file the correct way so that the content can be checked.
int main() {
char c[1000], file_name[1000];
int i;
int s = 0;
FILE *fp;
printf("Enter the name of file you wish to see\n");
gets(file_name);
if ((fp = fopen(file_name, "r")) == NULL){
printf("Error! opening file");
exit(1);
}
if (fp) {
while (fscanf(fp, "%s", c) != EOF) {
printf("%s", c);
}
fclose(fp);
for (i = 0; c[i] != '\0'; ++i) {
puts(c);
if (c[i] == 'e') {
++s;
}
}
printf("\nWhite spaces: %d", s);
_getche();
return 0;
}
}
char line[512]; /*To fetch a line from file maximum of 512 char*/
rewind(fp);
memset(line,0,sizeof(line)); /*Initialize to NULL*/
while ( fgets(line, 512, fp ) && fp !=EOF)
{
/*Suppose u want to analyze string "WELL_DONE" in this fetched line.*/
if(strstr(line,"WELL_DONE")!=NULL)
{
printf("\nFOUND KEYWOD!!\n");
}
memset(line,0,sizeof(line)); /*Initialize to null to fetch again*/
}
If its just a symbol you're looking for, or a char, you can simply use getc() :
int c;
....
if (fp) {
while ((c = getc(fp)) != EOF) {
if (c == 'e') {
// Do what you need
}
}
Or, alternatively, if it's a word you're looking for, fscanf() will do the job:
int c;
char symb[100];
char symbToFind[] = "watever"; // This is the word you're looking for
....
while ((c = fscanf(fp, %s, symb)) != EOF) {
if (strcmp(symb, symbToFind) == 0) { // strcmp will compare every word in the file
// do whatever // to symbToFind
}
}
These alternatives will allow you to search every char or string in the file, without having to save them as an array.

Resources