Can someone please help explain the difference in C and how my file fails to merge, and appends instead? The background is I am on an online computer science class this summer which uses C language, all we are given is read the entire texbook (732 pages), and do 20 projects over the course of 8 weeks, with no actual instruction, lecture, slides, or explanations. Please explain it so I can learn as I need to actually understand these terms to be better and progress in my Electrical Engineering program. I have contacted my professor for help but the answers are always short and uninformative, and you guys have provided so much more quality feedback to date. Also I do get that he is right and it was appended and not merged, but any feedback how i could of rectified this will help as well. Thank you again!
#include <stdio.h>
#include <stdlib.h>
FILE *inptr1, *inptr2, *outptr;
int main()
{
char c;
char file1[30], file2[30], file3[30];
printf("Enter the first files name\n");
gets(file1);
printf("Enter the second files name\n");
gets(file2);
printf("Enter the file name that will store the data from the other two files\n");
gets(file3);
inptr1 = fopen("C:\\Users\\Eric\\Desktop\\file1.txt","r");
inptr2 = fopen("C:\\Users\\Eric\\Desktop\\file2.txt","r");
if( inptr1 == NULL || inptr2 == NULL )
{
perror("Error ");
printf("Press any key to exit!\n");
exit(1);
}
outptr = fopen("C:\\Users\\Eric\\Desktop\\file3.txt","w");
if( outptr == NULL )
{
perror("Error ");
printf("Press any key to exit!\n");
exit(1);
}
while( ( c = fgetc(inptr1) ) != EOF )
fputc(c,outptr);
while( ( c = fgetc(inptr2) ) != EOF )
fputc(c,outptr);
printf("The two files were sucessfully merged into %s \n",file3);
fclose(inptr1);
fclose(inptr2);
fclose(outptr);
return 0;
}
Page 611 #5 Write a complete C program. Use the two files provided. Your program should not assume that you know which file is shorter.
5) Write a function to merge two sorted files of names and write the names to a
new file.
Was the only direction I was given as far as to what the program was supposed to do.
and this was the feedback i received, "Did you look at the resulting file?The girls names are all at the bottom. You were to merge the files,not append the files."
Thank you again in advance for your valuable feedback as it has taught me so much to date.
You're going to need to look at the contents of each file and write them to the third file in sorted order. That seems to be what the assignment is asking you to do. What you're doing currently is dumping the contents of file1.txt into file3.txt followed by the contents of file2.txt. You want to end up with a sorted list containing the contents of both files.
There are many ways to accomplish your requirements. This is just one that jumps out:
Steps to perform:
1 Open two existing files (fopen(fp, "r");), and one new file (fopen(fp, "w");)
2 write all lines of first file, then the second file to the third file. (fopen(), fgets(), fputs(), fclose(), etc.)
3 Read third file into an array of strings, keeping a count of the total number of strings read. close file.
4 Sort array of strings. (qsort())
5 Open third file, Write sorted array of strings into that file.
6 Close all files, free all memory.
Note, using this method, it does not matter if the two original files are sorted, or not, (Assignment says they are, but does not matter). The qsort routine will completely sort the string array either way.
qsort()
Most of the functions referenced are straight forward to use. qsort() is a little weird.
Here is an example showing how to set up qsort() for use sorting an array of strings:
For an array of strings: strings with the number of strings being say: cnt then:
qsort(strings, cnt, sizeof(char*), sortstring);
//With the function sortstring defined as:
static int sortstring( const void *str1, const void *str2 )
{
const char *rec1 = *(const char**)str1;
const char *rec2 = *(const char**)str2;
int val = strcmp(rec1, rec2);
return val;
}
string arrays
Creating an array of strings can also be challenging. Again, there are several ways to do this, here are two:
If you know the dimensions of each line, and the total number of lines in both files, then you can do it like this:
char strArray[numLines][longestLine];
If you don't, then you have to determine that at run-time by getting a count of the total number of lines, say when you are reading them from each file. And you will also need the length of the longest line found in both files, say by using strlen() on each one at some point as it is read or written. Once you have that information, you can create your string array like this:
char **strings=0;
Then, before you need it, create memory for it:
char **allocMemoryStr(char **strings, int numStrings, int maxLen)
{
int i;
strings = calloc(sizeof(char*)*(numStrings+1), sizeof(char*));
for(i=0;i<numStrings; i++)
{
strings[i] = calloc(sizeof(char)*maxLen + 1, sizeof(char));
}
return strings;
}
Finally, when you are finished using dynamically allocated memory, you must always free it:
void freeMemoryStr(char **strings, int numStrings)
{
int i;
for(i=0;i<numStrings; i++)
if(strings[i]) free(strings[i]);
free(strings);
}
Related
I am kind of new when it comes to C. Took a class on it in college but I just don't practice it much. Well my issue that I'm having is that I'm trying to take an text file and convert it into an array. I have been able to get the text file and print it into the console but when I save run the while statement to read each line, my whole array gets overwritten. For instance if my last line on my text file is 19, my array[0] gets over written to what should be on array[18].
I know the indentations are off a off, coding is a mess, and forgive me on the printf commands, I'm only using them to troubleshoot my code. The text file will have IP address on each line.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#define MAX_LINE_LENGTH 16
int main()
{
int lineCntPOSlist = 0;
int lineCnt = 0;
int i = 0;
FILE *textfile;
char line[MAX_LINE_LENGTH];
char* posList[50];
textfile = fopen("pos-list.txt", "r");
if(textfile == NULL)
{
int posListExist = 0;
system("cls");
printf("File Exist %d\n", posListExist);
fprintf(stderr, "**File open failed\n Make sure there is a pos-list.txt file");
return 1;
}
system("cls");
while(fgets(line, MAX_LINE_LENGTH, textfile))
{
printf("Line %d: %s",lineCnt , line);
posList[lineCnt] = line;
printf("posList[%d] = %s\n", lineCnt, posList[lineCnt] );
printf("posList[0] = %s\n", posList[0] );
lineCnt = ++lineCnt;
lineCntPOSlist = ++lineCntPOSlist;
}
fclose(textfile);
return 0;
}
This:
posList[lineCnt] = line;
simply sets posList[lineCnt] to point at the line buffer in line, it copies zero characters of actual data. In higher-level languages where strings have a bit more presence, this would make sense, but in C it doesn't.
Since there is only one line buffer, it will always hold the characters making up the most recently loaded line, and thus it will act as if previous lines are being "overwritten".
There are several solutions, here are a few:
Make posList into a proper array of strings, but that requires you to decide max length in advance and will waste the space for shorter lines.
Use something like strdup() to allocate copies on the heap of each line, and store pointers to those.
Use a more "proper" reallocating array for the storage and store line pointers (or offsets, which might be better suited due to the reallocating) in the array for easier access.
I’m a beginner at programming with C. I’m here because I need help from professional programmers. So, I have to do a simple program called “Lessons”. In this program, I need to use structure, an array of structure and use files to save all records.
For now, I have a struct
typed struct lessons{
char LessonName [30],
char TeacherName [20],
char TeacherLastName[20],
int numberOfStudents
} lessons
And array
lessons info[10]
As far I can understand I have an array called “info” which can handle 10 lessons information. Right?
And now I face up with my biggest problem. How should I “play” with all records?
Should I create a txt file and fill it up with some information or I should add the lesson’s information with code help?
Can anybody explain, give some examples of how should I put the new record to a static array when the user enters all information about the lesson?
And also, how to scan all records from (txt or bin) file and show it on console?
To make work easier I can give examples of records:
Physical education Harry Pleter 32
History Emily Shelton 12
If all string fields of the struct are a single word, you can do it like this:
for (int i = 0; i < sizeof info / sizeof info[0]; i++)
{
scanf("%29s %19s %19s %d", info[i].LessonName, info[i].TeacherName, info[i].TeacherLastName, &info[i].numberOfStudents);
}
This will work perfectly with the string "History Emily Shelton 12", but will however fail to work with the string "Physical education Harry Pleter 32", because Physical education is 2 words.
Reading more than one word per field
Reading more than 1 word per field can be done very similarly, but you will have to decide which is the character that separates the fields. In this example, I used comma ,:
for (int i = 0; i < sizeof info / sizeof info[0]; i++)
{
scanf("%29[^,] %19[^,] %19[^,] %d", info[i].LessonName, info[i].TeacherName, info[i].TeacherLastName, &info[i].numberOfStudents);
}
This will correctly parse the string: "Physical education, Harry, Pleter, 32". The commas are needed because the program needs to know when to stop reading a field and continue with the next one.
How should I “play” with all records?
How about 1 line of the file == 1 record?
Code needs 2 functions:
void lessons_write(FILE *destination, const lessons *source);
// return 1: success, EOF: end-of-file, 0: fail
int lessons_read(FILE *source, lessons *destination);
A key consideration: Input may not be formatted correctly and so calling code needs to know when something failed.
Consider comma separated values CSV.
void lessons_write(FILE *destination, const lessons *source) {
// Maybe add tests here to detect if the record is sane.
fprintf(destination, "%s, %s, %s, %d\n",
source->LessonName,
source->TeacherName,
source->TeacherLastName,
source->numberOfStudents);
}
int lessons_read(FILE *source, lessons *destination) {
// Use a buffer large enough for any reasonable input.
char buf[sizeof *destination * 2];
// Use fgets to read **1 line**
if (fgets(buf, sizeof buf, source) == NULL) {
return EOF;
}
// Use %n to detect end of scanning. It records the offset of the scan.
int n = 0;
sscanf(buf, " %29[^,], %19[^,], %19[^,], %d %n",
destination->LessonName,
destination->TeacherName,
destination->TeacherLastName,
&destination->numberOfStudents, &n);
// If scan did not complete or some junk at the end ...
if (n == 0 || buf[n] != '\0') {
return 0;
}
// Maybe add tests here to detect if the record is sane.
return 1;
}
Now armed with basics, consider more advanced issues:
Can a course name or teachers name contain a ',' or '\n' as that will foal up the reading? Perhaps form a bool Lessons_Valid(const lessons *source) test?
Can a course name or teachers name begin, contain or end with spaces? Or control characters?
What range is valid for # of students? Perhaps 0-9999.
How about long names?
A key to good record handling is the ability to detect garbage input.
give some examples of how should I put the new record to a static array when the user enters all information about the lesson?
How about some pseudo code to not take all the learning experience away?
open file to read, successful?
Set N as 10
lessons abc[N]
for up to N times
read record and return success
Was that the last (EOF)?
Was is a bad record (Error message)
else save it and increment read_count
close input
for read_count
print the record to stdout
I have a text file containing 5 words, and the second text file containing 2000 words I want to write a program in C language calculates the number of repeat words from first file in the second file and print the result on screen and I am new in C language , can any one help me to do it ...Thank you
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int read_line(FILE *in, char *buffer, size_t max)
{
return fgets(buffer, max, in) == buffer;
}
int main(void)
{
char b[2000];
int wcount = 0;
int j;
char i[5];
char File_path[40];
char stuff[5] = "False";
FILE *file1;
FILE *file2;
file1=fopen("test.txt", "r"); // my word list text file
file2=fopen("dickens-chimes-379.txt","r"); // my text file
for (j = 0; j < 5 && strcmp(i, stuff); j++)
{
fscanf(file1,"%s",i);
while (fgets(b,2000, file2)!=NULL)
{
if((strcat(b,i)) ==NULL)
{
wcount=0;
}
wcount++;
}
printf("%s %d\n",i,wcount);
wcount=0;
}
fclose(file1);
fclose(file2);
}
my input is (test.txt) have words (love,like,book,go, and test)
the output is love 4296 like 0 book 0 go 0 test 0
i need the real value of the words occurrence in file2
i found this code in the net and i don't know how to modify it because
i an new to c language .. i hope you could help to to write code for
same thing
I feel to mention that this is a fairly complicated problem for a beginner. I would suggest to get warmed up with simpler problems first.
Nevertheless, here are some high level thoughts:
Separate I/O from business logic
Read test.txt in a array of 5 words
Read a dickens.txt in a character array.
[If the file is really really big, then this strategy may need to be modified.]
Pass the test array and dickens array to the core function, say repeatFinder()
Very very high level pseudocode:
for each word w in test array:
scan dickens array
if w occurs in dickens:
w_counter +=1
advance dickens array
In C, you can use strstr( dickens, w ) [link] to find if w is present in dickens
I'm new to C and I am trying to figure out how I can search for a specific string and the number that follows it in a file that has several numbers and words.
The input file that I'm using looks like this:
TREES 2
BENCHES 5
ROCKS 10
PLANTS 8
I know how to make a function read a string and I know how to compare two strings but I don't know how to put them both together or how to set the array up to read through the whole file.
I've been using strcmp, but I just don't know how to go about initializing the word I'm trying to look for.
You could do something like this:
#include <stdio.h> // For file-handling methods
#include <string.h> // For strstr method
int main(void){
FILE *fp;
char *searchString="ROCKS";
fp = fopen("myfile.txt", "r");
char buf[100]; // Either char* buf or char buf[<your_buffer_size>]
int myNumber = -1;
while((fgets(buf, 100, fp)!=NULL)) { //good to handle error as well
if(strstr(buf, searchString)!=NULL) {
sscanf(buf + strlen(searchString), "%d", &myNumber);
break;
}
}
printf("After the loop, myNumber is %d\n", myNumber);
fclose(fp);
return (0);
}
Disclaimer - untested. Should be close...
Create an array that contains the words to search for. Create an outer loop that advances through your file stream of data one character offset at a time. Create a second inner loop that iterates over your array of terms to search for. The inner loop examines each term in the array against the data provided by the outer loop. Use strncmp to limit the length of each compare to the length of the word being searched for. Upon a match, check the following character in the source buffer to ensure it doesn't negate the match.
Im currently learning C through random maths questions and have hit a wall. Im trying to read in 1000 digits to an array. But without specifiying the size of an array first i cant do that.
My Answer was to count how many integers there are in the file then set that as the size of the array.
However my program returns 4200396 instead of 1000 like i hoped.
Not sure whats going on.
my code: EDIT
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
FILE* fp;
const char filename[] = "test.txt";
char ch;
int count = 0;
fp = fopen(filename, "r");
if( fp == NULL )
{
printf( "Cannot open file: %s\n", filename);
exit(8);
}
do
{
ch = fgetc (fp);
count++;
}while (ch != EOF);
fclose(fp);
printf("Text file contains: %d\n", count);
return EXIT_SUCCESS;
}
test.txt file:
731671765313306249192251196744265747423553491949349698352031277450632623957831801698480186947885184385861560789112949495459501737958331952853208805511
125406987471585238630507156932909632952274430435576689664895044524452316173185640309871112172238311362229893423380308135336276614282806444486645238749
303589072962904915604407723907138105158593079608667017242712188399879790879227492190169972088809377665727333001053367881220235421809751254540594752243
525849077116705560136048395864467063244157221553975369781797784617406495514929086256932197846862248283972241375657056057490261407972968652414535100474
821663704844031998900088952434506585412275886668811642717147992444292823086346567481391912316282458617866458359124566529476545682848912883142607690042
242190226710556263211111093705442175069416589604080719840385096245544436298123098787992724428490918884580156166097919133875499200524063689912560717606
0588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450
Any help would be great.
You forgot to initialize count, so it contains random garbage.
int count = 0;
(But note that with this change it's still not going to work, since %d in a scanf format means read as many digits as you find rather than read a single digit.)
Turn on your compiler's warnings (-Wall), it will tell you that you didn't initialize count, which is a problem: it could contain absolutely anything when your program starts.
So initialize it:
int count = 0;
The other problem is that the scanfs won't do what you want, at all. %d will match a series of digits (a number), not an individual digit. If you do want to do your counting like that, use %c to read individual characters.
Another approach typically used (as long as you know the file isn't being updated) is to use fseek/ftell to seek to the end of the file, get the position (wich will tell you its size), then seek back to the start.
The fastest approach though would be to use stat or fstat to get the file size information from the filesystem.
If you want number of digits thin you tave to do it char-by-char e.g:
while (isdigit(fgetc(file_decriptor))
count++;
Look up fgetc, getc and scanf in manpages, you don't seem to understand whats going on in your code.
The way C initializes values is not specified. Most of the time it's garbage. Your count variable it's not initialized, so it mostly have a huge value like 1243435, try int count = 0.