-
Splitting up a string
my input file will contain:
ABC|DEF|91
XYZ|LDS|78
Output should be:
First Name..........Last Name..........Grade
ABC......................DEF...................... .91
XYZ......................LDS...................... .78
I am trying to get it to split at the '|' points.
Question:
I am trying to break this up into first name, last name, and grade. I have been able to get it to split the first name and grade and print those out, but getting it to split the 3rd time is giving me trouble.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person{
char name[30];
int age;
};
int main(int args, char *argv[])
{
struct person list[30];
int i,n;
char *ch,*ch1;
char buf[256];
FILE *fp;
fp = fopen(argv[1],"r");
if(fp == NULL){
printf("Cannot open file %s\n", argv[1]);
exit(0);
}
i=0;
fgets(buf,256,fp);
while(!feof(fp)){
ch = strchr(buf,'\n');
if(ch != NULL) *ch = '\0';
else break;
ch = strchr(buf,'|');
if(ch != NULL){
*ch = '\0';ch1 = ++ch;
}
else break;
strcpy(list[i].name,buf);
list[i].age = atoi(ch1);
i++;
fgets(buf,256,fp);
}
n = i;
for (i = 0; i < n; i++)
printf("%s is %d years old\n",list[i].name,list[i].age);
return 0;
printf("
}
In present form the current code will take:
ABC|78
XYZ|56
and outprint:
First Name.......................Last Name.......................Grade
ABC...................................________.... ......................78
XYZ...................................________.... ......................56
So I feel like I'm pretty close. Anybody have ideas or pointers? THANKS!
-
You try the following code.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person{
char firstname[30]; //array for storing the firstname
char lastname[30]; //array for storing the lastname
int age; //age for storing the age of the person
};
int main(int args, char *argv[])
{
struct person list[30];
int i,n;
char *ch,*ch1,*ch2,*ch3; //declaring pointers to character
char buf[256];
FILE *fp;
fp = fopen(argv[1],"r");
if(fp == NULL){
printf("Cannot open file %s\n", argv[1]);
exit(0);
}
i=0;
fgets(buf,256,fp);
while(!feof(fp)){
ch = strchr(buf,'\n');
if(ch != NULL) *ch = '\0';
else break;
ch = strchr(buf,'|'); //searching for the character | in buf and returning the pointer if it matched
ch2 = strrchr(buf,'|'); //searching the pipe character from the end of the string and it returns the pointer
if(ch != NULL)
{
*ch = '\0';ch1 = ++ch2; //moving the end pointer one position to point to the age value instead of |
}
else break;
ch++; //moving the pointer to point to the first character of the last name after first name instead of |
strcpy(ch3,ch); //copying the content lastname|age to ch3 string
ch2=strchr(ch3,'|'); //searching for the character | in the ch3
*ch2='\0'; //making that position as null to print only the last name
strcpy(list[i].firstname,buf); //copying the first name from buffer to structure
strcpy(list[i].lastname,ch3); //copying the lasst name from buffer to structure
list[i].age = atoi(ch1); //storing the age into structure
i++;
fgets(buf,256,fp);
}
n = i;
for (i = 0; i < n; i++)
printf("%s's last name %s and he is %d years old\n",list[i].firstname,list[i].lastname,list[i].age);
return 0;
}
-
Hey thanks a lot. Would you mind explaining what you added and what how it works or what it does?
-
Are you trying for this? See one more Example.
Code:
#include <stdio.h>
#include <string.h>
#include<stdlib.h>
#include<malloc.h>
char *replace(char *str, char *old, char *new) {
int i, count = 0;
int new_len = strlen(new);
int old_len = strlen(old);
for (i = 0; str[i]; ++i)
if (strstr(&str[i], old) == &str[i])
++count, i += old_len - 1;
char *buffer = (char *) calloc(i + 1 + count * (new_len - old_len), sizeof(char));
if (!buffer) return;
i = 0;
while (*str)
if (strstr(str, old) == str)
strcpy(&buffer[i], new),
i += new_len,
str += old_len;
else
buffer[i++] = *str++;
buffer[i] = '\0';
return buffer;
}
int main() {
FILE *fp;
char *buf;
fp = fopen("input_file","r");
int i=0;
buf=malloc(1056);
fread(buf,1056,1056,fp);
buf = replace(buf, "|", "---");
printf("%s",buf);
}
-
thanks for the reply ungalnanban, but that isn't quite what i was looking for.
-
thanks vivekraj! I appreciate your time
-
-
Thanks guys for the help!!!
Ok got another predicament.
So here is the input in the form of lastname|firstname|grade:
ABC|DEF|123
so last name is ABC
first name is DEF
grade is 123
I am wanting to check that every set has a last name and grade, they are allowed to not have a first name
for example if i had input of:
|DEF|123
ABC|DEF|
I want it to reject these and continue on to the next line. Ultimate goal is to write the "rejected" inputs to a file called rejected, but I can do that on my own. I just need help getting started with how to go about checking to make sure I have the required fields in my input file.
-
I gather that you have already written the code to read from file into an array of struct person? You should modify that read process such that it checks that the last name and grade when read are not empty.
-
ok....it goes through and pulls ABC and stores it in array ch3, then pulls DEF and stores it, and pulls 123 and stores it. Is there a way that I could check and see if nothing was stored? something like.....
if (ch3 = '\0' ) can i do that? since it's an array. just say "if" it only contains \0 reject it.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person{
char firstname[30];
char lastname[30];
char grade;
float age;
};
int main(int args, char *argv[])
{
struct person list[30];
int i,n;
char *ch,*ch1,*ch2,ch3[50],assignedGrade[1];
char buf[256];
FILE *fp;
fp = fopen(argv[1],"r");
if(fp == NULL){
printf("Cannot open file %s\n", argv[1]);
exit(0);
}
i=0;
fgets(buf,256,fp);
while(!feof(fp))
{
ch = strchr(buf,'\n');
if(ch != NULL) *ch = '\0';
else break;
ch = strchr(buf,'|');
ch2 = strrchr(buf,'|');
if(ch != NULL)
{
*ch = '\0';ch1 = ++ch2;
}
else break;
ch++;
strcpy(ch3,ch);
ch2=strchr(ch3,'|');
*ch2='\0';
char grade;
strcpy(list[i].firstname,buf);
strcpy(list[i].lastname,ch3);
list[i].age = atof(ch1);
int getGrade;
getGrade = atof(ch1);
switch ( getGrade/10) {
case 9:
assignedGrade[0] = 'A';
break;
case 8:
assignedGrade[0] = 'B';
break;
case 7:
assignedGrade[0] = 'C';
break;
default:
assignedGrade[0] = 'F';
break;
}
list[i].grade = assignedGrade[0];
i++;
fgets(buf,256,fp);
}
n = i;
printf("Last Name First Name Grade Letter Grade \n");
for (i = 0; i < n; i++)
printf("%s %s %4.2f %c\n",list[i].firstname,list[i].lastname,list[i].age, list[i].grade);
return 0;
}
Part of this code is irrelevant to my question, but this is my code as it sits now. It compiles and runs. Just needed to add the step I talked about.
-
Try the following algorithm for your additional requirement.
Code:
- Check the firstname whether it is a null.
- Compare the current lastname with next record lastname .
- The above 2 conditions are true , move that record to your target file.
-
Code:
fgets(buf,256,fp);
while(!feof(fp)){
fgets(buf,256,fp);
}
This you can simply replace with
Code:
while ( fgets(buf,sizeof buff,fp) != NULL ) {
}
@ungalnanban
> buf=malloc(1056);
> fread(buf,1056,1056,fp);
1. Where did 1056 come from?
2. fread would read up to 1056*1056 -> massive buffer overflow
3. fread() does NOT append a \0, so the later string operations are broken.
Plenty of other mistakes for the observant as well.
Also, you need to work on your indentation. The code is all but unreadable posted on a forum.
Check your IDE settings, and make sure it is set to "use spaces for tabs".
Clever IDEs can make sense of mixed spaces and tabs, but HTML can't.
-
First off, a really appreciate the help everyone has provided me! I have learned alot in the past few days. I believe I am VERY close to finishing this. One thing I lack is to sort the person(s) by last name. I added a swap function and a sort function, but am unsure where and how to call upon them. Any advice would be helpful, my code is as follows.
Code:
/*This program reads in a list of names, verifies their structure,
* sorts them by last name, calculates their letter grade, and
* prints all relevant information in a sorted list*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Assigns the structure of a person
struct person{
char firstName[30];
char lastName[30];
char grade;
float points;
};
// Swap function
void swap(struct person *p1,struct person *p2)
{
char z;
float x;
char temp[30];
char temp1[30];
strcpy(temp, p1->lastName);
strcpy(temp1, p1->firstName);
z = p1 -> grade;
x = p1 -> points;
strcpy(p1 ->lastName,p2->lastName);
strcpy(p1 ->firstName,p2->firstName);
p1 ->grade = p2->grade;
p1 ->points = p2->points;
strcpy(p2 ->lastName,temp);
strcpy(p2 ->firstName,temp);
p2->grade=z;
p2->points=x;
}
// Sort function
void psort(int n, struct person student[])
{
int i;
int j;
for (i=0; i < n; i++)
for (j=i+1; j<n; j++)
if (strcmp(student[i].lastName,student[j].lastName) > 0)
swap(&student[i],&student[j]);
}
// Beginning of main
int main(int args, char *argv[])
{
struct person student[30];
int i,n,gradeCalculate;
int a=0,b=0,c=0,d=0,f=0;
char *ch,*ch1,*ch2;
char ch3[10];
char buf[256];
FILE *fp;
FILE *fp2;
// Makes sure files and loads it to buf
fp = fopen(argv[1],"r");
if(fp == NULL){
printf("Cannot open file\n");
exit(0);
}
i=0;
fgets(buf,256,fp);
// Validates that person has a last name and grade
while(!feof(fp)){
if(buf[0] != '|' && buf[strlen(buf)-2] != '|')
{
// Splits the last name, first name, and grade
ch = strchr(buf,'\n');
if(ch != NULL) *ch = '\0';
else break;
ch = strchr(buf,'|');
ch2 = strrchr(buf,'|');
if(ch != NULL)
{
*ch = '\0';ch1 = ++ch2;
}
else break;
ch++;
strcpy(ch3,ch);
ch2=strchr(ch3,'|');
*ch2='\0';
gradeCalculate = atoi(ch1);
strcpy(student[i].lastName,buf);
strcpy(student[i].firstName,ch3);
student[i].points = atof(ch1);
// Calculates the letter grade
switch(gradeCalculate / 10)
{
case 10:
student[i].grade = 'A';
break;
case 9:
student[i].grade = 'A';
break;
case 8:
student[i].grade = 'B';
break;
case 7:
student[i].grade = 'C';
break;
default:
student[i].grade = 'F';
}
// Increments letter counter
if(gradeCalculate >= 90) a++;
if(gradeCalculate >= 80 && gradeCalculate < 90) b++;
if(gradeCalculate >= 70 && gradeCalculate < 80) c++;
if(gradeCalculate < 70) f++;
fgets(buf,256,fp);
i++; // Increments the student array
}
else
{
fp2 = fopen("REJECTS.txt","a");
fprintf(fp2,"%s",buf);
fclose(fp2);
fgets(buf,256,fp);
}//
} // End of While statement
// Prints the format for the Grade list
n = i;
printf("\n Grade list for CS-XXXX \n");
printf(" ---------------------- \n\n");
printf("Last Name First Name");
printf(" Points Grade \n");
printf("--------- ----------");
printf(" ------ ----- \n");
// Runs a loop to print the array information
for (i = 0; i < n; i++){
// Prints the array of students
printf("%-30s %-30s %4.2f ",student[i].
lastName,student[i].firstName,student[i].points);
printf("%c\n",student[i].grade);
}
// Prints the class summary
printf("\n Grade Summary for CS-XXXX \n");
printf(" ------------------------- \n\n");
printf(" # of A's %d\n",a);
printf(" # of B's %d\n",b);
printf(" # of C's %d\n",c);
printf(" # of D's %d\n",d);
printf(" # of F's %d\n",f);
return 0;
}