I have a .txt file following the syntax:
studentName1 grade1
studentName2 grade2
.
.
.
I want to develop the C function int changeGrade(String name, int old_grade, int new_grade, String fileName)
That changes the grade of the specified Student with the new one.
#include <stdio.h>
#include <string.h>
typedef char String[30];
void changeGrade(String name, int old_grade, int new_grade, String fileName) {
long pos;
String temp;
int grade;
int test = 0;
if ((old_grade <= 10) && (old_grade >= 0)) {
FILE * fp = fopen(fileName, "r+");
while ((!test) && (!feof(fp))) {
pos = ftell(fp);
fscanf(fp, "%s %d\n", temp, & grade);
if (strcmp(name, temp) == 0 && grade == old_grade) {
fseek(fp, pos, SEEK_SET);
fprintf(fp, "%s %d", name, new_grade);
test = 1;
}
}
fclose(fp);
} else printf("Error,you must specify the grade");
}
int main(int argc,
const char * argv[]) {
changeGrade("Carl", 7, 6, "students.txt");
}
The code works, but if i have something like
changeGrade("Carl",10,7,"students.txt") I get
Carl 70
Why?
Although I cannot condone doing this in C, nor the approach you are currently taking, the simple fix is for you to ensure that all your grades are the same width. If you must preprocess the file to make everything 2 digits, do that with something like: awk '{$2 = sprintf("%2d",$2)}1' input-file
Once that is done, just use a 2 digit grade all the time. That is, write:
fprintf(fp, "%s %2d", name, new_grade);
Related
Can you guys please check this and tell me what am I doing wrong?
I am trying to read from a txt into a struct
The file looks like this: (name on a line, followed by 4 attributes on the next line)
NAME SURNAME OTHER
a1 a2 a4 a3
OTHER ANOTHER
s2 s3 s4 s5
I have to read the file into a struct, then search for a name and print the number of comparisons it took till you found it (the names in the file are alphabetically sorted - I guess binary search is optimal).
Here is what I wrote for now:
*note: I know for certain that the file will have 10000 lines and the full name has at most 40 chars
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct student
{
char name[40];
char arg1[10];
char arg2[10];
char arg3[10];
char arg4[10];
}STUD;
STUD studies[5000];
STUD *ptr = studies;
void readlines(FILE *f)
{
char line[40];
char secondline[40];
int i=0;
while(fgets(line, 40, f) != NULL) //read first line -> here has to be student's name
{
sscanf(line, "%[^\n]%*c\n", studies[i].name); //store first line ->student's name
fgets(secondline, 40, f); //read second line -> here has to be additional information
sscanf(secondline, "%s %s %s %s", studies[i].arg1, studies[i].arg2, studies[i].arg3, studies[i].arg4);
i++;
}
}
void binary_search_string(STUD *arr, char x[])
{
//printf("sizeof: %ld\n", sizeof(arr));
int l=0;
int r = 4999;
int mid;
int compare=0;
while(l <= r)
{
mid = (l + r)/2;
printf("%s\n", studies[mid].name);
if(strcmp(studies[mid].name, x) == 0)
{
compare++;
printf("%d comparisons to find %s\n", compare, x);
break;
}
else
{
if(strcmp(studies[mid].name, x) < 0)
{
compare++;
l = mid + 1;
}
else
{
compare++;
r = mid - 1;
}
}
//printf("compare: %d\n", compare);
}
}
void print(STUD *array)
{
for(int i=0; i<sizeof(array); i++)
{
printf("%s %s %s %s %s\n", studies[i].name, studies[i].arg1, studies[i].arg2, studies[i].arg3, studies[i].arg4);
}
}
int main(int argc, char **argv)
{
if(argc < 2)
{
printf("usage: ./exe file_to_open\n");
exit(-1);
}
FILE *fp = fopen(argv[1], "r");
if(fp == NULL)
{
return 1;
}
char x[]="SURNAME NAME";
readlines(fp);
print(studies);
binary_search_string(studies, x);
fclose(fp);
return 0;
}
Another thing I am not sure about is how would the function "readlines" look like when using the pointer to the array of struct (ptr). (Can you guys give me an example here?)
I am sorry in advance if this is a stupid question.
Thank you!
I want to write data in structure to a text file. But it ends up showing strange characters in the text file. I have changed many forms of fwrite arguments but none works. Please someone help me. Sorry for the long code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student
{
char name[30];
int id;
int score;
int score2;
int score3;
};
int main()
{
printf("Please input the information below into grade.data!\n");
printf("Ends with name's value equal to 'E'\n");
struct Student stu[10];
int i = 0, maxlength = 0; //size of longest name
printf("Name No Math Chi Eng\n");
while (true){
scanf("%s", stu[i].name);
if(maxlength < strlen(stu[i].name)) maxlength = strlen(stu[i].name);
if (stu[i].name[0] == 'E') break;
scanf("%d", &stu[i].id);
scanf("%d", &stu[i].score1);
scanf("%d", &stu[i].score2);
scanf("%d", &stu[i].score3);
i++;
}
FILE* fp;
fp = fopen("test.txt", "wb");
if (fp == NULL) {
printf("Open file error!");
exit(-1);
}
fwrite(&stu, sizeof(struct Student), 1, fp);
fclose(fp);
printf("Name%-*c No%-*c Math Chi Eng\n", maxlength-4, ' ', 7, ' ');
for (int i = 0; stu[i].name[0] != 'E'; i++) {
printf("%-*s ", maxlength, stu[i].name);
printf("%-*d ", 9, stu[i].id);
printf("%-*d ", 4, stu[i].score1);
printf("%-*d ", 3, stu[i].score2);
printf("%d\n", stu[i].score3);
}
return 0;
}
It because members in the structure Student other than name are integers. Convert integer values to ASCII and then store it in the file.
Have a problem to read in a file in c. Have been searching online since I'm a beginner in programming but still I have a problem with the output of my file.
int main( int argc, char *argv[]){
FILE *in;
int chr;
if(in = fopen("airmap1.map", "r")) == NULL){
printf("Could not open file\n");
exit(1);
while(fgets(row, sizeof(row),in) !=NULL){
if (*row == '#') //next row
continue;
fscanf(in, "%*[^\n]s , %[]s", row);
}
}
The file I want to read in is looking like this:
#animals at the zoo
cat dog #cat-dog
fish frog #fish-frog
I want to ignore comments after this sign #, but my problem is that my code only ignore the first word after #. But right now it gives me this output:
cat frog
dog fish
How can i solve this problem? I would like to have the output this form instead:
cat dog
fish frog
You could use a function that checks for any "#" in every line of the file, and then copy it in another string.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define commentSign '#'
#define bufferLength 255
int findPosOfChar(char * buffer, char charToFind, int length)
{
int i;
for(i = 0 ; i < length ; i++)
{
if(buffer[i] == charToFind)
return i;
}
return 0;
}
int main( int argc, char *argv[]){
FILE* filePointer = fopen("test", "r");
char buffer[bufferLength];
char *p = malloc(sizeof(char) * 255);
int commentPos;
while(fgets(buffer, bufferLength, filePointer)) {
commentPos = findPosOfChar(buffer, (char)commentSign, bufferLength);
memcpy(p, buffer, commentPos);
p[commentPos] = '\0';
printf("%s\n", p);
}
fclose(filePointer);
}
I am trying a program in c to read a text file that contains array of characters or a string and find the number of occurrences of the substring called "GLROX" and say sequence found when it is found. And the "inputGLORX.txt" contains following string inside it.
GLAAAROBBBBBBXGLROXGLROXGLROXGLROXGLCCCCCCCCCCCCCCROXGGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROX
But i am getting wierd results. It would be great if some expert in C-programming helps me to solve this and thanks in advance.
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define NUMBER_OF_STRINGS 40
#define MAX_STRING_SIZE 7
void seqFound()
{
printf("Sequence Found\n");
}
int main()
{
FILE *fp;
char buff[1000];
char strptrArr[NUMBER_OF_STRINGS] [MAX_STRING_SIZE];
const char *search = "GLROX";
fp = fopen("D:/CandC++/inputGLORX.txt", "r");
if(fp==NULL)
printf("It is a null pointer");
while(!feof(fp))
{
//fscanf(fp, "%s", buff);
fgets(buff, 1000,fp);
}
int len = strlen(buff);
printf("length is %d\n",len);
int count = 0;
char *store;
while(store = strstr(buff, search))
{
printf("substring is %s \n",store);
count++;
search++;
}
printf("count is %d\n",count);
while (count!=0) {
seqFound();
count--;
}
return 0;
}
As said in the comment, their are at least 2 problems in the code: your fgets will only fetch the last line (if it fetch one at all ? In any case, this is not what you want), and you are incrementing the search string instead of the buff string.
Something like this should fix most of your problems, as long as no lines in your file are longer than 999 characters. This will not work properly if you use the \n or NULL characters in your search string.
int count = 0;
while (fgets(buff, 1000, fp) != NULL)
{
char *temp = buff;
while ((temp = strstr(temp, search)))
{
printf("%d. %s\n", count + 1, temp);
count++;
temp++;
}
}
Here is a main for testing. I used argv to provide the input.txt and the search string.
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
FILE *fp;
char buff[1000];
char *search;
if (argc < 3)
return (-1);
search = argv[2];
if (search[0] == '\0')
return (-1);
if ((fp = fopen(argv[1], "r")) == NULL)
return (-1);
int count = 0;
while (fgets(buff, 1000, fp) != NULL)
{
char *temp = buff;
while ((temp = strstr(temp, search)))
{
printf("%d. %s\n", count + 1, temp);
count++;
temp++;
}
}
printf("Match found: %d\n", count);
return 0;
}
The way you search in buff is wrong, i.e. this code:
while(store = strstr(buff, search))
{
printf("substring is %s \n",store);
count++;
search++; // <------- ups
}
When you have a hit, you change search, i.e. the string you are looking for. That's not what you want. The search string (aka the needle) shall be the same all the time. Instead you want to move forward in the buffer buff so that you can search in the remainder of the buffer.
That could be something like:
int main()
{
const char* buff = "GLAAAROBBBBBBXGLROXGLROXGLROXGLROXGLCCCCCCCCCCCCCCROXGGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROXGLROX";
const char* search = "GLROX";
const char* remBuff = buff; // Pointer to the remainder of buff
// Initialized to be the whole buffer
const char* hit;
int cnt = 0;
while((hit = strstr(remBuff, search))) // Search in the remainder of buff
{
++cnt;
remBuff = hit + 1; // Update the remainder pointer so it points just 1 char
// after the current hit
}
printf("Found substring %d times\n", cnt);
return 0;
}
Output:
Found substring 15 times
I tried to write a program for counting number of words in a text that taken from a file. I have a problem, the compiler can not find my file however I put this file in project folder.
what can I do?
#include <stdio.h>
#include <conio.h>
#include <string.h>
int words(const char sentence[ ]);
int main(void) {
char sentence[100];
FILE *cfPtr;
if ( (cfPtr = fopen("C programming.dat", "r")) == NULL ) {
printf( "File could not be opened\n" );
}
else {
fscanf(cfPtr, "%s", sentence);
}
words(sentence);
printf("%d", words(sentence));
getch();
return 0;
}
int words(const char sentence[ ]) {
int i, length = 0, count = 0, last = 0;
length = strlen(sentence);
for (i = 0; i < length; i++)
if (sentence[i] == ' ' || sentence[i] == '\t' || sentence[i] == '\n')
count++;
return count;
}
I'll try to improve usability of your program, accepting a filename as optional parameter
int main(ant argc, char *argv[]) {
char sentence[100];
const char *filename = "C programming.dat";
FILE *cfPtr;
if (argc == 2)
filename = argv[1];
if ( (cfPtr = fopen(filename, "r")) == NULL ) {
printf( "File '%s' could not be opened\n", filename );
}
else {
int total = 0;
while (fgets(sentence, sizeof sentence, cfPtr))
total += words(sentence);
printf("%d", total);
fclose(cfPtr);
}
getch();
return 0;
}
...
note: untested
If the file is not in the working directory (the folder your program is in) you need to specify the entire file path. On a Linux machine this would be something like "/home/your-user-name/Desktop/text.txt". For a Windows machine it would be "c:\\your\\file\path\\text.txt". If the file is in your working directory and the program still cannot find it, then it probably doesn't like the white space in the file name. Try naming it CProgramming.dat and see if that works.