dynamic memory reading from a file - c

I desperately need some help with an exercise my professor gave me. Essentially, I'm making a program using a structure and dynamic memory where it'll read a file where each line has one word, and it'll print to a new file each unique word and how many times it was in the file.
So for instance, if the file going in had this
apple
orange
orange
The file it prints to would say
apple 1
orange 2
So far, this is my code
#include <stdio.h>
#include <stdlib.h>
struct wordfreq {
int count;
char *word;
};
int main(int argc, char *argv[]){
int i;
char *temp;
FILE *from, *to;
from = fopen("argc[1]","r");
to = fopen("argv[1]","w");
struct wordfreq w1[1000];
struct wordfreq *w1ptr[1000];
for(i = 0; i < 1000; i++)
w1ptr[i] = NULL;
for(i = 0; i < 1000; i++)
w1ptr[i] = (struct wordfreq*)malloc(sizeof(struct wordfreq));
while(fscanf(from,"%256s",temp)>0){
}
for(i = 999; i >= 0; i--)
free(w1ptr[i]);
}
w1ptr should store a word from the file in the wordfreq file, then increment count in that array. I have no clue how to go about storing the word in *word though. Any help would be greatly appreciated

This is how in general your read/write from a file
const int maxString = 1024; // put this before the main
const char * fn = "test.file"; // file name
const char * str = "This is a literal C-string.\n";
// create/write the file
puts("writing file\n");
FILE * fw = fopen(fn, "w");
for(int i = 0; i < 5; i++) {
fputs(str, fw);
}
fclose(fw);
puts("done.");
// read the file
printf("reading file\n");
char buf[maxString];
FILE * fr = fopen(fn, "r");
while(fgets(buf, maxString, fr)) {
fputs(buf, stdout);
}
fclose(fr);
remove(fn); // to delete a file
puts("done.\n");

Related

string of undetermined length c

Hi I was trying to create an array of string of an undetermined length in c.
This is my code :
int main()
{
int lineCount=linesCount();
char text[lineCount][10];
printf("%d",lineCount);
FILE * fpointer = fopen("test.txt","r");
fgets(text,10,fpointer);
fclose(fpointer);
printf("%s",text);
return 0;
}
I would like to replace 10 in
char text[lineCount][10];
My code reads out a file I already made the amount of lines dynamic.
Since the line length is unpredictable I would like to replace 10 by a something dynamic.
Thanks in advance.
To do this cleanly, we want a char * array rather than an 2D char array:
char *text[lineCount];
And, we need to use memory from the heap to store the individual lines.
Also, don't "hardwire" so called "magic" numbers like 10. Use an enum or #define (e.g) #define MAXWID 10. Note that with the solution below, we obviate the need for using the magic number at all.
Also, note the use of sizeof(buf) below instead of a magic number.
And, we want [separate] loops when reading and printing.
Anyway, here's the refactored code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
linesCount(void)
{
return 23;
}
int
main(void)
{
int lineCount = linesCount();
char *text[lineCount];
char buf[10000];
printf("%d", lineCount);
// open file and _check_ the return
const char *file = "test.txt";
FILE *fpointer = fopen(file, "r");
if (fpointer == NULL) {
perror(file);
exit(1);
}
int i = 0;
while (fgets(buf, sizeof(buf), fpointer) != NULL) {
// strip newline
buf[strcspn(buf,"\n")] = 0;
// store line -- we must allocate this
text[i++] = strdup(buf);
}
fclose(fpointer);
for (i = 0; i < lineCount; ++i)
printf("%s\n", text[i]);
return 0;
}
UPDATE:
The above code is derived from your original code. But, it assumes that the linesCount function can predict the number of lines. And, it doesn't check against overflow of the fixed length text array.
Here is a more generalized version that will allow an arbitrary number of lines with varying line lengths:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(void)
{
int lineCount = 0;
char **text = NULL;
char buf[10000];
// open file and _check_ the return
const char *file = "test.txt";
FILE *fpointer = fopen(file, "r");
if (fpointer == NULL) {
perror(file);
exit(1);
}
int i = 0;
while (fgets(buf, sizeof(buf), fpointer) != NULL) {
// strip newline
buf[strcspn(buf,"\n")] = 0;
++lineCount;
// increase number of lines in array
text = realloc(text,sizeof(*text) * lineCount);
if (text == NULL) {
perror("realloc");
exit(1);
}
// store line -- we must allocate this
text[lineCount - 1] = strdup(buf);
}
fclose(fpointer);
// print the lines
for (i = 0; i < lineCount; ++i)
printf("%s\n", text[i]);
// more processing ...
// free the lines
for (i = 0; i < lineCount; ++i)
free(text[i]);
// free the list of lines
free(text);
return 0;
}

Replace a word in a text file, then output the overwritten version

For this problem I'm asked to first read from the input text file, prompt the user which word/string to get replaced, then output the same file (the original gets overwritten). The thing is the input/outputfile name must always have a specific name for example test.txt (this is what bothers me)
Here's the function which I tested out and it does the job replacing, but for now I'm prompting user to enter their own "sentence" and then for words. I'm lost on how to (always) read from a test.txt and then output the same one with replaced string.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *w_replace(const char *s, const char *oldone, const char *newone)
{
char *ret;
int i, count = 0;
int newlen = strlen(newone);
int oldonelen = strlen(oldone);
for (i = 0; s[i] != '\0'; i++)
{
if (strstr(&s[i], oldone) == &s[i])
{
count++;
i += oldonelen - 1;
}
}
ret = (char *)malloc(i + count * (newlen - oldonelen));
if (ret == NULL)
exit(EXIT_FAILURE);
i = 0;
while (*s)
{
if (strstr(s, oldone) == s) //compare
{
strcpy(&ret[i], newone);
i += newlen;
s += oldonelen;
}
else
ret[i++] = *s++;
}
ret[i] = '\0';
return ret;
}
int main(void)
{
char mystr[100], c[10], d[10];
char fileOld[32] = "test.txt";
char fileNew[32] = "test.txt";
char word_search[80];
char word_replace[80];
FILE *fp1, *fp2;
fp1 = fopen(fileOld,"r");
fp2 = fopen(fileNew,"w");
printf("Enter the word to replace :\n");
scanf(" %s",word_search);
printf("Enter the new word:\n");
scanf(" %s",word_replace);
char *newstr = NULL;
newstr = w_replace(fileOld, word_search , word_replace);
fputs(word_replace, fp2);
fclose(fp2);
fclose(fp1);
return 0;
}
So if a test.txt contains the following sentence
This is a test
Result
Enter the word to replace :
This
Enter the new word:
That
The new updated test.txt file will only be
That
instead of
That is a test
Needed values (using the var names you gave above):
#include <fcntl.h>
int file_descriptor;
int size_of_text = <whatever you want here>;
char *file_name = "test.txt";//or whatever
char newone[size_of_text];
char oldone[size_of_text];
To read from a file:
file_descriptor = open(file_name,O_RDONLY);//O_RDONLY opens for read only
read(file_descriptor,oldone,sizeof(oldone));//reads file into oldone
close(file_descriptor);//closes so you don't accidentally read or write to it later, and so you can use it again
To write to a file:
file_descriptor = open(file_name,O_WRONLY | O_TRUNC);//O_WRONLY opens for writing only, O_TRUNC will truncate the file if it exists
write(file_descriptor,newone,sizeof(newone);//writes newone to file
close(file_descriptor);
For more information on read(),write(),open(),close():
http://www.gdsw.at/languages/c/programming-bbrown/c_075.htm

Assigning each line of a file into each element of an array

I'm quite new to C programming and have just begun studying files. I'm wondering whether it is possible to read a file line by line (including spaces in each line) into an array of size equal to the number of lines in the file. I really have no idea where to start or whether this is even possible so any guidance at all would be much appreciated.
Example
A text file in the form of:
Computer Programming
Software Engineering
Computer Architecture
to be written into array such that:
char array[4];
array[0] = "Computer Programming";
array[1] = "Software Engineering";
array[2] = "Computer Architecture";
All I have so far is:
int main()
{
char array[50];
bool answer;
FILE *classes;
classes = fopen("classnames.txt", "r");
if(classes == NULL){
printf("\n ************* ERROR *************\n");
printf("\n \"classnames.txt\" cannot be opened.\n");
printf("\n PROGRAM TERMINATED\n");
exit(EXIT_FAILURE);
}
And next I would like to write each class name into each element of the array.
Yes, you just have to declare array as char** and dynamically allocate as you read each line. E.g.
int MAX_NUM_LINES = 1000;
int MAX_LINE_LEN = 256;
char** array;
malloc(array, MAX_NUM_LINES*sizeof(char*));
fp = fopen(...);
int line_ct = 0;
char line[MAX_LINE_LEN];
while ( fgets(line, MAX_LINE_LEN, fp) != NULL )
{
int len = strlen(line);
malloc(array[line_ct], len * sizeof(char));
strcpy(array[line_ct], line);
line_ct++;
}
I have not actually tried to compile this code, but something like this will work. You can also replace MAX_NUM_LINES with the actual value by doing a quick runthrough first and counting the lines--that would be preferable probably.
This is an example of a possible approach
#include <stdio.h>
#include <string.h>
int main()
{
char array[100][100];
char line[100];
size_t arraySize;
size_t count;
FILE *file;
const char *filepath;
filepath = "<put the file path here>";
file = fopen(filepath, "r");
if (file == NULL)
{
perror("fopen()");
return -1;
}
count = 0;
arraySize = sizeof(array) / sizeof(array[0]);
while ((fgets(line, sizeof(line), file) != NULL) && (count < arraySize))
{
size_t length;
length = strlen(line);
if (line[length] == '\0')
line[--length] = '\0';
memcpy(array[count++], line, 1 + length);
}
fclose(file);
return 0;
}

Opening files with sequential filenames

For an assignment I'm trying to output multiple files with different names e.g. file_1.dat, file_2.dat etc. I was hoping I could do this the same way as fprintf and fscanf but that doesn't work.
What would anyone suggest (code below is what I used)
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i;
for( i = 0; i < 3; i++)
{
FILE *file;
file = fopen("testing_%d.dat", i,"w");
}
}
sprintf should come in handy.
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i;
for( i = 0; i < 3; i++)
{
char buf[100]
FILE *file;
sprintf(buf, "testing_%d.dat", i);
file = fopen(buf, "w");
}
}
You can first write the file name to a char [] by using sprintf(), and then pass it to fopen().
char myFile[200];
sprintf(myFile, "testing_%d.dat", i);
file = fopen(myFile, "w");
file should be an array of FILE *. Also, fopen doesn't format a string like printf. Change your file opening logic to something like this:
#define NUM_FILES (3)
#define FILE_NAME_LENGTH (100)
FILE *pFileArr[NUM_FILES];
char filename[FILE_NAME_LENGTH];
for(i = 0; i < NUM_FILES; i++)
{
snprintf(filename, FILE_NAME_LENGTH, "testing_%d.dat", i);
pFileArr[i] = fopen(filename, "w");
}

Use strings from a function to main function

One of my functions reads lines from a text file and stores into a variable. I need a way to use that variable in my main function. I've tried several methods and nothing has worked. Can anyone help me?
#include <stdio.h>
#include <string.h>
int test(const char *fname, char **names){
char usernames[250][50];
FILE *infile;
char buffer[BUFSIZ];
int i =0;
infile = fopen(fname, "r");
while(fgets(buffer,50,infile)){
strcpy(usernames[i],buffer);
printf("%s",usernames[i]);
i++;
}
int x, y;
for(y = 0; y < 250; y++)
for(x = 0; x < 50; x++)
usernames[y][x] = names[y][x];
return 0;
}
int main()
{
char *names;
test("test.txt", &names);
}
Can anyone help? I haven't coded in C in a long time.
In C, the caller should allocate the memory for the strings it needs, otherwise, no one knows who's supposed to free memory. Then you can pass a pointer to a function that will populate it.
int main() {
char names[250][50];
test("test.txt", names);
for (int i=0; i < 50; i++) {
printf("File %d: %s", i, names[i], 250);
}
}
void test(const char *fname, char(*names)[50], int maxWords){
FILE *infile;
int i =0;
char buffer[50];
infile = fopen(fname, "r");
while(fgets(buffer,50,infile) && i < maxWords){
strcpy(usernames[i],names[i]);
i++;
}
}

Resources