can't parse next word in char array using strtok - c

#include"shell.h"
int main()
{
char cInput[50];
char cCopy[50];
char *pCommand;
char pArguement[10];
bool bRun = true;
while(strcmp(pCommand, "exit"))//run untill exit
{
printf("[myshell]%% ");
cin >> cInput; //get command from user
for(int i=0; i<50; i++)
cCopy[i] = cInput[i];
//get command
pCommand = strtok(cInput, " ");
if(!strcmp(pCommand, "pwd"))
{
printf("No FUNCTIONAILITY FOR PWD! \n");
}
else if(!strcmp(pCommand, "list"))
{
printf("No FUNCTIONAILITY FOR LIST! \n");
}
else if(!strcmp(pCommand, "history"))
{
printf("No FUNCTIONAILITY FOR HISTORY! \n");
}
else if(!strcmp(pCommand, "prompt"))
{
// pCommand = strtok(cCopy, "y");
while(pCommand != NULL)
{
printf(" %s \n", pCommand);
pCommand = strtok(NULL, " ");
}
return 0;
}
else//command not found
{
printf("%s: Command not found \n", pCommand);
}
}
return 0;
}
So I'm trying to follow the example of strtok from the C standard library, but I can't figure out why I'm unable to get the next word from the cstring cInput. I was under the impression that using:
while(pCommand != NULL)
{
printf(" %s \n", pCommand);
pCommand = strtok(NULL, " ");
}
would result in getting the next words.
Any help?
Thanks!

Related

How to make if-statement print required the result?

This code has one problem. The problem is in
Problem in if-statement
if(all_digits(to_find) && strlen(to_find) == 13)
Whenever I enter 13 characters but not from the file then it gives me a message of else statement but printing Found. Hello World! also. Although Found. Hello World! is in if-statement. It should not be printed. How to make if-statement work correctly?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int all_digits(char *s){
for (; *s!=0; s++){
if (!isdigit(*s)){
return 0;
}
}
return 1;
}
Another part of code
int main(){
FILE * fr = fopen("file.csv", "r");
char save[500], line[200], to_find[50];
int oneByOne = 0, numberOfFields=8;
char *word = NULL;
printf("Enter the ID card number: ");
scanf("%s", to_find);
if(all_digits(to_find) && strlen(to_find) == 13){
while(fgets(line, 200, fr)){
word = strtok(line, "\n");
strcpy(save, line);
if (strstr(save, to_find)){
char *wordone = strtok(save, ",");
while (wordone != NULL){
printf("Here are your details: %s\n", wordone);
wordone = strtok(NULL, ",");
}
}
}
fclose(fr);
printf("Found. Hello World!\n");
}
else {
printf("enter correclty\n");
}
return 0;
}
To run multiple tests without cascading if-thens you can use an error flag along with a one-time loop like so:
int err = 0; /* Be optimistic! (0 indicates success) */
do {
if (!test1-passed) {
err = 1;
break;
}
if (!test2-passed) {
err = 2;
break;
}
...
if (!testN-passed) {
err = N;
break;
}
printf("Success! All tests passed");
} while (0);
if (err) {
printf("Test %d failed", err);
}
Applied to you particular problem the code might look like this
... /* definitions here */
int err = 0; /* Be optimistic! (0 indicates success) */
do {
... /* input here */
do {
if (!all_digits(to_find)) {
err = 1;
break;
}
if (strlen(to_find) != 13) {
err = 2;
break;
}
{
err = 3 /* be pessimistic! */
while(fgets(line, 200, fr)){
/* word = strtok(line, "\n"); */ /* word is not needed. */
strcpy(save, line); /* Introducing save here is not necessary,
all following operation can be applied to line. */
if (strstr(save, to_find)){
char *wordone = strtok(save, ",");
while (wordone != NULL){
printf("Here are your details: %s\n", wordone);
wordone = strtok(NULL, ",");
err = 0; /* Phew, we are lucky! */
}
}
}
if (err) {
break;
}
}
printf("Success! All tests passed");
} while (0);
if (err) {
printf("Test %d failed", err);
}
} while (err);

Searching a name in a text file by ID

I have a text file with 2 lines in it:
Voicu;Catalin;1234;2.32
Diana;Cadar;2345;1.01
I'm trying to make my program search in .txt file the ID (1234 or 2345) and match it to the name. Below is the code I've tried to make, but it won't find the ID in .txt after I write it in first scanf, the first thing that appears is the "else" line.
void alegereStudent(struct student *stud)
{
FILE *scStudenti = fopen("studenti.txt", "a");
char *error;
int i=0,n;
if(scStudenti==NULL)
{
error = strerror(errno);
printf("Fisierul nu poate fi creat: \n %s", error);
}
printf("\nIntroduceti Numele: ");
scanf("%39s", stud->numeStudent);
printf("Introduceti Prenumele: ");
scanf("%39s", stud->prenumeStudent);
printf("Introduceti ID-ul studentului: ");
scanf("%d", &stud->idStudent);
printf("Introduceti Media de admitere: ");
scanf("%f", &stud->medieAdmitere);
fprintf(scStudenti,"<%s>;", stud->numeStudent);
fprintf(scStudenti,"<%s>;", stud->prenumeStudent);
fprintf(scStudenti,"<%d>;", stud->idStudent);
fprintf(scStudenti,"<%.2f>\n", stud->medieAdmitere);
fclose(scStudenti);
}
//
void optiunea_2()
{
printf("\n1.Despre studenti.\n");
printf("2.Despre profesori.\n");
printf("3.Revenire la meniu principal.\n");
printf("\nAlegeti o optiune: ");
scanf("%d",&alegere_opt2);
switch(alegere_opt2)
{
case 1: while(&stud!=NULL)
{
FILE *scStudenti = fopen("studenti.txt", "r");
char *error;
int cautareID;
if(scStudenti==NULL)
{
error = strerror(errno);
printf("Fisierul nu poate fi creat: \n %s", error);
}
printf("\nIntroduceti ID-ul studentului: ");
scanf("%d", &cautareID);
fscanf(scStudenti,"%d",&stud->idStudent);
if(cautareID==&stud->idStudent)
{
printf("Numele Studentului este %s %s",&stud->numeStudent, &stud->prenumeStudent);
}
else
printf("\nAcest ID nu exista!\n");
optiunea_2();
}break;
fprintf(scStudenti,"<%s>;", stud->numeStudent);
fprintf(scStudenti,"<%s>;", stud->prenumeStudent);
fprintf(scStudenti,"<%d>;", stud->idStudent);
fprintf(scStudenti,"<%.2f>\n", stud->medieAdmitere);
fclose(scStudenti);
This makes formatting much more difficult. The output file will contain:
<first>;<last>;<1234>;<0.5>
You want to start with a new file and simplify the output to write:
first;last;1234;0.5
Don't always put & in front of integer. Just use:
if(cautareID == stud->idStudent)
{
...
}
Example:
const char *filename = "studenti.txt";
void alegereStudent()
{
struct student stud;
FILE *scStudenti = fopen(filename, "a");
if(scStudenti == NULL)
{
printf("error\n");
return;
}
printf("\nIntroduceti Numele: ");
scanf("%39s", stud.numeStudent);
printf("Introduceti Prenumele: ");
scanf("%39s", stud.prenumeStudent);
printf("Introduceti ID-ul studentului: ");
scanf("%d", &stud.idStudent);
printf("Introduceti Media de admitere: ");
scanf("%f", &stud.medieAdmitere);
fprintf(scStudenti, "%s;", stud.numeStudent);
fprintf(scStudenti, "%s;", stud.prenumeStudent);
fprintf(scStudenti, "%d;", stud.idStudent);
fprintf(scStudenti, "%.2f\n", stud.medieAdmitere);
fclose(scStudenti);
}
void find_by_id(int id)
{
FILE *fin = fopen(filename, "r");
if(!fin)
return;
int count = 0;
struct student stud;
while(fscanf(fin, "%39[^;];%39[^;];%d;%f\n",
stud.numeStudent, stud.prenumeStudent, &stud.idStudent, &stud.medieAdmitere) == 4)
{
if(id == stud.idStudent)
{
printf("found %s %s\n", stud.numeStudent, stud.prenumeStudent);
}
count++;
}
if(count == 0)
printf("failed to read any record. Start with a new file.\n");
}
int main(void)
{
alegereStudent();
find_by_id(1234);
return 0;
}
If <> characters are added, then read according to that format, you then have to remove the extra <> characters from the string.
void alegereStudent()
{
struct student stud;
...
fprintf(scStudenti, "<%s>;", stud.numeStudent);
fprintf(scStudenti, "<%s>;", stud.prenumeStudent);
fprintf(scStudenti, "<%d>;", stud.idStudent);
fprintf(scStudenti, "<%.2f>\n", stud.medieAdmitere);
fclose(scStudenti);
}
void find_by_id(int id)
{
...
struct student stud;
while(fscanf(fin, "%39[^;];%39[^;];<%d>;<%f>\n",
stud.numeStudent, stud.prenumeStudent, &stud.idStudent, &stud.medieAdmitere) == 4)
{
if(id == stud.idStudent)
{
char *p;
size_t i;
//remove the extra <> characters
p = stud.numeStudent;
if (strlen(p) > 1)
{
for(i = 1; i < strlen(p) - 1; i++)
p[i - 1] = p[i];
p[i - 1] = 0;
}
//remove the extra <> characters
p = stud.prenumeStudent;
if (strlen(p) > 1)
{
for(i = 1; i < strlen(p) - 1; i++)
p[i - 1] = p[i];
p[i - 1] = 0;
}
printf("found %s %s\n", stud.numeStudent, stud.prenumeStudent);
}
count++;
}
if(count == 0)
printf("failed to read any record. Start with a new file.\n");
}
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char const *filename = "test.txt";
FILE *input = fopen(filename, "r");
if (!input) {
fprintf(stderr, "Couldn't open \"%s\" for reading!\n\n", filename);
return EXIT_FAILURE;
}
char name[101];
char surname[101];
int id;
double value;
while (fscanf(input, "%100[^;];%100[^;];%d;%lf%*[\n]", name, surname, &id, &value) == 4) {
if (id == 2345) {
printf("Found \"%s %s\" by id %d\n\n", name, surname, id);
break;
}
}
}

Remove element from struct type

I'm trying to create this function to remove an element of the user's choosing from a pointer struct array type.
Here is my function. I keep getting this error when my code hits this function.
error: incompatible types when assigning to type ‘char[1000]’ from type ‘char *’
PhoneBook[iRecord - 1].cFirstName = PhoneBook[x].cFirstName;
void delete_record(pb *PhoneBook)
{
int x;
int iRecord = 0;
print(PhoneBook);
printf("\nEnter number of record you want to delete: ");
scanf("%d", &iRecord);
printf("\nRecord to be deleted: %d. %s\n", iRecord - 1, PhoneBook[iRecord - 1].cFirstName);
for (x = strlen(PhoneBook[iRecord - 1].cFirstName); x <= strlen(PhoneBook[iRecord - 1].cFirstName); x--) {
PhoneBook[iRecord - 1].cFirstName = PhoneBook[x].cFirstName;
}
printf("\nModified record: %s\n\n",PhoneBook[iRecord - 1].cFirstName);
}
Here's the full code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct phonebook {
char cFirstName[1000];
char cLastName[1000];
char cNumber[1000];
} pb;
int entry(pb *);
void modify(pb *);
void delete_record(pb *);
void print(pb *);
void convert_u(char *);
//global variable
int MAX_NAME_ENTRY = 0;
int main()
{
int iResponse = 0;
pb *PhoneBook = (pb *) calloc(0, sizeof(pb));
if (PhoneBook == NULL) {
printf("\nMemory allocation failed.\n\n");
return 1;
}
do {
printf("\nPhonebook Menu\n****************\n\n");
printf("1. Enter new contact\n2. Modify existing contact\n3. Delete contact\n4. Print Phonebook \n5. Exit\n\n");
printf("Please make selection: ");
scanf("%d", &iResponse);
if (iResponse == 1) {
entry(PhoneBook);
}
else if (iResponse == 2) {
modify(PhoneBook);
}
else if (iResponse == 3) {
delete_record(PhoneBook);
//printf("\nWorking on it...\n");
}
else if (iResponse == 4) {
print(PhoneBook);
}
} while (iResponse != 5);
free(PhoneBook);
return 0;
}
int entry(pb *PhoneBook)
{
int x;
char yes_no[] = "YES";
pb *newPhoneBook = realloc(PhoneBook, (10 * sizeof(pb)));
if (newPhoneBook == NULL) {
printf("\nOut of memory!\n\n");
return 1;
}
else {
PhoneBook = newPhoneBook;
}
if (MAX_NAME_ENTRY == 10) {
printf("\nMax Number of names entered.\n");
}
for (x = MAX_NAME_ENTRY; x < 10; x++) {
if (MAX_NAME_ENTRY == 9) {
printf("\nLast entry.\n");
}
if (x > 0) {
system("clear");
printf("\nAnother entry(yes/no)? ");
scanf("%s", yes_no);
convert_u(yes_no);
}
if (strcmp(yes_no, "YES") == 0) {
printf("\nFirst Name: ");
scanf("%s", PhoneBook[x].cFirstName);
printf("\nLast Name: ");
scanf("%s", PhoneBook[x].cLastName);
printf("\nPhone Number: ");
scanf("%s", PhoneBook[x].cNumber);
MAX_NAME_ENTRY++;
}
else if (strcmp(yes_no, "NO") == 0) {
break;
}
}
}
void modify(pb *PhoneBook)
{
int iModify = 0;
char name_num[6] = {'\0'};
print(PhoneBook);
printf("\nWhich entry would you like to modify? ");
scanf("%d", &iModify);
printf("\nModify name or number? ");
scanf("%s", name_num);
convert_u(name_num);
if (strcmp(name_num, "NAME") == 0) {
printf("\nEnter new name: ");
scanf("%s %s", PhoneBook[iModify - 1].cFirstName, PhoneBook[iModify - 1].cLastName);
}
else if (strcmp(name_num, "NUMBER") == 0) {
printf("\nEnter new number: ");
scanf("%s", PhoneBook[iModify - 1].cNumber);
}
}
void delete_record(pb *PhoneBook)
{
int x;
int iRecord = 0;
print(PhoneBook);
printf("\nEnter number of record you want to delete: ");
scanf("%d", &iRecord);
printf("\nRecord to be deleted: %d. %s\n", iRecord - 1, PhoneBook[iRecord - 1].cFirstName);
for (x = strlen(PhoneBook[iRecord - 1].cFirstName); x <= strlen(PhoneBook[iRecord - 1].cFirstName); x--) {
PhoneBook[iRecord - 1].cFirstName = PhoneBook[x].cFirstName;
}
printf("\nModified record: %s\n\n",PhoneBook[iRecord - 1].cFirstName);
}
void print(pb *PhoneBook)
{
int x;
for (x = 0; x < 10; x++) {
if (strlen(PhoneBook[x].cFirstName) == 0 && strlen(PhoneBook[x].cLastName) == 0) {
break;
}
printf("\n%d. Name: %s %s", x + 1, PhoneBook[x].cFirstName, PhoneBook[x].cLastName);
printf("\n Number: %s\n\n", PhoneBook[x].cNumber);
}
}
void convert_u(char *string)
{
int x;
for (x = 0; x < strlen(string); x++) {
string[x] = toupper(string[x]);
}
}
Any suggestions on what I'm doing wrong?
An array name is not a modifiable lvalue. Hence, arrays are not assignable in C.
Quoting C11, chapter §6.5.16
An assignment operator shall have a modifiable lvalue as its left operand.
and regarding the modifiable lvalue, chapter §6.3.2.1
A modifiable lvalue is an lvalue that
does not have array type, [...]
You need to use strcpy() instead to copy the content.
it will not work strcpy, you have to copy the whole record over the other. then realloc the phonebook to new size.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct phonebook {
char cFirstName[50];
char cLastName[50];
char cNumber[50];
} pb;
int entry();
void modify();
void delete_record();
void print_record(int rec);
void print();
void convert_u(char *);
//global variables
int MAX_NAME_ENTRY = 0;
pb *PhoneBook = NULL;
#define YES "YES"
#define NO "NO"
const char *menu=
" Phonebook Menu \n"
" **************** \n"
" \n"
" 1. Enter new contact \n"
" 2. Modify existing contact \n"
" 3. Delete contact \n"
" 4. Print Phonebook \n"
" 5. Exit \n"
" \n"
" Please make selection: ";
int main(void){
int iResponse = 0;
do {
printf("%s",menu);
scanf("%d", &iResponse);
switch (iResponse) {
case 1:
entry();
break;
case 2:
modify();
break;
case 3:
delete_record();
break;
case 4:
print();
}
} while (iResponse != 5);
free(PhoneBook);
return 0;
}
int str_input(const char *text, char *buff){
printf("%s" , text);
scanf("%s" , buff);
}
int entry(void)
{
int x;
char yes_no[] = YES;
pb *newPhoneBook;
if (MAX_NAME_ENTRY == 10) {
printf("\nMax Number of names entered.\n");
return 0;
}
while(1) {
newPhoneBook = realloc(PhoneBook,(MAX_NAME_ENTRY +1) * sizeof(pb)) ;
if (!newPhoneBook) {
perror("entry::realloc()");
return 1;
}
PhoneBook = newPhoneBook;
if (MAX_NAME_ENTRY == 9) {
printf("\n *** This is the Last entry. *** \n");
}
printf("RECORD: %d\n",MAX_NAME_ENTRY+1);
str_input("\nFirst Name: " , PhoneBook[MAX_NAME_ENTRY].cFirstName);
str_input("\nLast Name: " , PhoneBook[MAX_NAME_ENTRY].cLastName);
str_input("\nPhone Number: " , PhoneBook[MAX_NAME_ENTRY].cNumber);
MAX_NAME_ENTRY++;
if(MAX_NAME_ENTRY == 10)
break;
printf("\nAnother entry(yes/no)? ");
scanf("%s", yes_no);
convert_u(yes_no);
if (strcmp(yes_no, YES))
break;
system("clear");
}
}
int checkRecordExists(int iRecord){
if(iRecord<1 || iRecord>MAX_NAME_ENTRY){
printf("Record %d do not exists\n",iRecord);
return 0;
}
return 1;
}
void modify(void){
int iModify = 0;
char name_num[6] = {'\0'};
printf("\nWhich entry would you like to modify? ");
scanf("%d", &iModify);
if(!checkRecordExists(iModify))
return;
iModify --;
print_record(iModify);
str_input("\nModify name or number? ", name_num);
convert_u(name_num);
if (strcmp(name_num, "NAME") == 0) {
str_input("\nFirst Name: " , PhoneBook[iModify].cFirstName);
str_input("\nLast Name: " , PhoneBook[iModify].cLastName);
}
else if (strcmp(name_num, "NUMBER") == 0) {
str_input("\nPhone Number: " , PhoneBook[iModify].cNumber);;
}
}
void delete_record(void)
{
int x;
int iRecord = 0;
printf("\nEnter number of record you want to delete: ");
scanf("%d", &iRecord);
if(!checkRecordExists(iRecord))
return;
iRecord--;
MAX_NAME_ENTRY--;
for( x=iRecord;x<MAX_NAME_ENTRY;x++)
memcpy(&PhoneBook[x],&PhoneBook[x+1],sizeof(pb));
PhoneBook = realloc(PhoneBook,(MAX_NAME_ENTRY + 1) * sizeof(*PhoneBook) );
}
void print_record(int rec){
printf("\n"
"%02d. Name: %s %s\n"
" Number: %s\n"
"\n",
rec + 1, PhoneBook[rec].cFirstName, PhoneBook[rec].cLastName, PhoneBook[rec].cNumber);
}
}
void print(void){
int x;
for (x = 0 ; x < MAX_NAME_ENTRY ; x++) {
print_record(x);
}
}
void convert_u(char *string){
while(*string){
*string = toupper(*string);
string ++;
}
}

Program stuck in cycle

I'm trying to implement a C program for CRC for my laboratory exam. I've written the following code. But, it is same as the main source code but it got stuck at strcpy(). I can't figure it out. Here's the source code:
#include <stdio.h>
#include <string.h>
int ctoi(char a) {
return (a-48);
}
char itoc(int a) {
return (a+48);
}
void main() {
int ld, lm, i, j;
char div[20], ip[100], ipm[100], crc[10], snd[100]={0}, rcv[100];
printf("\t\t\tCRC Encoding\n");
printf("Enter the codeword: ");
scanf("%s",ip);
printf("Enter the divisor: ");
scanf("%s",div);
strcpy(ipm, ip);
lm = strlen(ipm);
ld = strlen(div);
if(lm>=ld) {
//padding
for(i=lm, j=0; j<ld-1; j++)
ipm[i++] = '0';
ipm[i] = '\0';
printf("Data word after appending zeroes: %s\n", ipm);
for(i=0;i<ld;i++)
crc[i] = ipm[i];
crc[i] = '\0';
for(;i<strlen(ipm);i++) {
if(crc[0] == '1') {
for(j=0; j<ld; j++)
crc[j] = itoc((ctoi(crc[j])) ^ (ctoi(div[j])));
}
crc[ld] = ipm[i];
crc[ld+1] = '\0';
for(j=0;crc[j]!='\0';j++)
crc[j] = crc[j+1];
crc[j] = '\0';
}
for(j=0;crc[j]!='\0';j++)
crc[j] = crc[j+1];
crc[j] = '\0';
printf("CRC remainder is: %s\n",crc);
strcat(snd, ip);
strcat(snd, crc);
printf("Sent codeword: %s\n",snd);
printf("CRC Decoding\n");
strcpy(rcv, snd);
printf("after strcpy");
printf("Received codeword: %s", rcv);
for(i=0;i<ld;i++) {
crc[i] = rcv[i];
}
crc[i] = '\0';
for( ;i<strlen(rcv);i++) {
if(crc[0]=='1') {
for(j=0;j<ld;j++) {
crc[j] = itoc((ctoi(crc[j])) ^ (ctoi(div[j])));
}
}
crc[ld] = rcv[i];
crc[ld+1] = '\0';
for (j = 0; crc[j]!='\0'; i++) {
crc[j] = crc[j+1];
}
crc[j] = '\0';
for(j=0; crc[j]!='\0'; j++) {
if(crc[j]!='0')
break;
}
printf("CRC remainder is: %s\n",crc);
if(j==strlen(crc)) {
printf("Received message is error free\n");
} else {
printf("Received message contains errors\n");
}
}
} else {
printf("Enter a proper divisor");
}
}
And the output screen is:
CRC Encoding
Enter the codeword: 10110
Enter the divisor: 110
Data word after appending zeroes: 1011000
CRC remainder is: 00
Sent codeword: 1011000
CRC Decoding
It is stuck at the above line. But the correct program is here:
#include<stdio.h>
#include<string.h>
int ctoi(char a)
{
return(a-48);
}
char itoc(int a)
{
return(a+48);
}
void main()
{
char ip[100],ipm[100],div[20],crc[10],sent[100]={0},rec[100];
int i,lm,ld,j;
printf("\nCRC encoding");
printf("\nEnter data word(message)");
scanf("%s",ip);
printf("\nEnter the divisor");
scanf("%s",div);
strcpy(ipm,ip);
lm=strlen(ipm);
ld=strlen(div);
if(lm>=ld)
{
for(i=lm,j=0;j<ld-1;j++)
ipm[i++]='0';
ipm[i]='\0';
printf("\nData word after appending zeros:%s",ipm);
for(i=0;i<ld;i++)
crc[i]=ipm[i];
crc[i]='\0';
for(;i<strlen(ipm);i++)
{
if(crc[0]=='1')
{ for(j=0;j<ld;j++)
{
crc[j]=itoc((ctoi(crc[j]))^(ctoi(div[j])));
}
}
crc[ld]=ipm[i];
crc[ld+1]='\0';
for(j=0;crc[j]!='\0';j++)
crc[j]=crc[j+1];
crc[j]='\0';
}
for(j=0;crc[j]!='\0';j++)
crc[j]=crc[j+1];
crc[j]='\0';
printf("\nCRC remainder is:%s",crc);
strcat(sent,ip);
strcat(sent,crc);
printf("\nCode word in sender side is:%s",sent);
printf("\nCRC decoing");
strcpy(rec,sent);
//rec[2]='1';
printf("\nReceived message in receiver side is :%s",rec);
for(i=0;i<ld;i++)
crc[i]=rec[i];
crc[i]='\0';
for(;i<strlen(rec);i++)
{
if(crc[0]=='1')
{
for(j=0;j<ld;j++)
{
crc[j]=itoc((ctoi(crc[j]))^(ctoi(div[j])));
}
}crc[ld]=rec[i];
crc[ld+1]='\0';
for(j=0;crc[j]!='\0';j++)
crc[j]=crc[j+1];
crc[j]='\0'; }
for(j=0;crc[j+1]!='\0';j++)
crc[j]=crc[j+1];
crc[j]='\0';
for(j=0;crc[j]!='\0';j++)
{
if(crc[j]!='0')
break;
}
printf("\nCRC remainder is:%s",crc);
if(j==strlen(crc))
printf("\nReceived message is error free!\n\n");
else
printf("\nError in received message!!!\n\n");
}
else
printf("\nEnter proper divisor");
}
And it runs perfect. I can't able to find the difference between these two programs even though I went through line by line. Can you tell me what's wrong with the first program?
The problem arises from a small typo in your code. You wrote
for (j = 0; crc[j]!='\0'; i++) {
crc[j] = crc[j+1];
}
but it should have been
for (j = 0; crc[j]!='\0'; j++) {
crc[j] = crc[j+1];
}
Mind the j++. Of course, the call to strcpy() is no culprit!

Sorting array filled with lines of string

I have a data in text like this:
1,jack,3,7.3
2,mike,4,8.6
3,gol,2,9
Could any one help me how to sort the data by the last column that represent the grades in descending using c language?
The question was posted before but with no code so I posted it again to get more help.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct
{
int cid;
char name[40];
char term[2];
double gpa;
}student;
typedef struct
{
char line[300];
}data;
typedef struct
{
int cid;
}finds;
typedef struct
{
double score;
}gpa;
void menu();
int calculateMax(void);
void addStudent();
void find();
void display();
void sort();
int main()
{
menu();
system("PAUSE");
return 0;
}
void menu()
{
int selection;
printf("%s", "Program menu :\n");
printf("%s", "1. Add a new student\n");
printf("%s", "2. Find/retrieve information for a particular Student\n");
printf("%s", "3. Display STUDENTS list\n");
printf("%s", "4. Find a student that has the lowest and the highest deposit\n");
printf("%s", "5. Quit\n");
printf("%s", "Selection : ");
scanf("%d", &selection);
if(selection == 1)
{
addStudent();
}
else if(selection == 2)
{
find();
}
else if(selection == 3)
{
display();
}
else if(selection == 4)
{
sort();
}
else if(selection == 5)
{
exit(0);
}
else {
printf("%s", "\n\aError, please key in correct input!\n\n");
menu();
}
}
void addStudent()
{
int max, i;
FILE *f, *id, *name, *term, *gpa , *sort;
printf("%s", "\n\nADD student\n");
printf("%s", "How many students you would like to add : ");
scanf("%d", &max);
student *student_info;
student_info = (student *) malloc(max * sizeof(student)); /*Allocate Memory For Client's Info*/
if(student_info == NULL)
{
printf("Unable to allocate space for client\n\n");
exit (EXIT_FAILURE);
}
if ((id = fopen("id.txt", "a+")) == NULL) /*Open file id.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((name = fopen("name.txt", "a+")) == NULL) /*Open file name.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((term = fopen("term.txt", "a+")) == NULL) /*Open file TERM.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((gpa = fopen("gpa.txt", "a+")) == NULL) /*Open file GPA.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((f = fopen("student.txt", "a+")) == NULL) /*Open file STUDENTS.txt*/
{
printf("Error, the file cannot be opened\n");
}
if ((sort = fopen("sort.txt", "a+")) == NULL) /*Open file SORT.txt*/
{
printf("Error, the file cannot be opened\n");
}
else {
for (i = 0; i < max ; i++) { /*Get the input data*/
printf("student %d\n", i + 1);
printf("%s", "student's Id : ");
scanf("%5d", &student_info[i].cid);
printf("%s", "student's Name : ");
fflush(stdin);
gets(student_info[i].name);
printf("%s", "student's term : ");
fflush(stdin);
gets(student_info[i].term);
printf("%s", "student's GPA : ");
scanf("%7lf", &student_info[i].gpa);
printf("\n");
}
}
for(i = 0; i < max; i++) { /*Store input data into files*/
fprintf(id, "%d\n", student_info[i].cid);
fputs(student_info[i].name, name);
fprintf(name, "\n");
fputs(student_info[i].term, term);
fprintf(term, "\n");
fprintf(gpa, "%lf\n", student_info[i].gpa);
fprintf(sort,"%d,%s,%s,%lf\n",student_info[i].cid,student_info[i].name,student_info[i].term,student_info[i].gpa);
}
for(i = 0; i < max; i++) {
fprintf(f, "%d", student_info[i].cid, "");
fprintf(f, "%3s", "");
fputs(student_info[i].name, f);
fprintf(f, "%5s", "");
fputs(student_info[i].term, f);
fprintf(f, "%7s", "");
fprintf(f, "%lf\n", student_info[i].gpa);
}
fclose(f);
fclose(id);
fclose(name);
fclose(term);
fclose(gpa);
fclose(sort);
free(student_info);
student_info = NULL;
printf("\n");
menu();
}
void find()
{
int find_id = 0, i = 0, student_cid, n = 0, max, selection;
FILE *id, *f;
max = calculateMax();
finds *result;
result = (finds *) malloc(max * sizeof(finds));
if(result == NULL)
{
printf("Unable to allocate space for student\n\n");
exit (EXIT_FAILURE);
}
if ((id = fopen("id.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
else {
while (!feof(id)) { /*Get all clients' id number and store to array*/
fscanf(id, "%d", &result[i].cid);
i++;
}
}
fclose(id);
printf("%s", "\n\nFIND STUDENT\n");
printf("%s", "Key in Student's id : "); /*Get the client's id that user want to query*/
scanf("%d", &student_cid);
data *student_info;
student_info = (data *) malloc(max * sizeof(data));
if(student_info == NULL)
{
printf("Unable to allocate space for student\n\n");
exit (EXIT_FAILURE);
}
if ((f = fopen("student.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
i = 0;
while (!feof(f)) { /*Get all the students' data from clients.txt and stored to array*/
fflush(stdin);
fgets(student_info[i].line, 300, f);
i++;
}
fclose (f);
for(i = 0; i < max + 1; i++)
{
if(student_cid == result[i].cid)
{
printf("\n\n%s%6s%20s%17s\n", "ID", "NAME", "TERM", "GPA");
puts(student_info[i].line);
free(student_info);
student_info = NULL;
free(result);
result = NULL;
printf("Would you like to find another student?\nKey in 1 for yes or 2 to go to menu : ");
scanf("%d",&selection);
if(selection == 1) {
find();
}
else if(selection == 2) {
menu();
}
break;
}
else if(i == max)
{
printf("\nSory, there's no student with that exist in database.\n");
free(student_info);
student_info = NULL;
free(result);
result = NULL;
printf("Would you like to find another student?\nKey in 1 for yes or 2 to go to menu : ");
scanf("%d",&selection);
if(selection == 1) {
find();
}
else if(selection == 2) {
printf("\n\n");
menu();
}
}
}
}
void display()
{
int max = 0, i;
FILE *f;
printf("\n\nDISPLAY STUDENT");
max = calculateMax();
data *student_info;
student_info = (data *) malloc(max * sizeof(data));
if(student_info == NULL)
{
printf("Unable to allocate space for student\n\n");
exit (EXIT_FAILURE);
}
if ((f = fopen("student.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
i = 0;
while (!feof(f)) {
fflush(stdin);
fgets(student_info[i].line, 200, f);
i++;
}
fclose (f);
printf("\n\n%s%6s%20s%17s\n", "ID", "NAME", "TERM", "GPA");
for(i = 0; i < max; i++)
{
puts(student_info[i].line);
}
free(student_info);
student_info = NULL;
}
int calculateMax(void)
{
char str[150];
int maximum = 0;
FILE *f;
if ((f = fopen("student.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
else {
while (!feof(f)) {
maximum++;
fgets (str , 200 , f);
}
}
fclose (f);
maximum = maximum - 1;
return maximum;
}
////////////////////////////////////////////////////////////////////
static int student_info_compare(const void *a, const void *b)
{
const student_info *sia = a, *sib = b;
return strcmp(sia->name, sib->name);
}
void Sortdisplay()
{
int max = 0, i;
FILE *f;
printf("\n\nDISPLAY SORTED STUDENT");
max = calculateMax();
data *student_info;
student_info = (data *) malloc(max * sizeof(data));
if(student_info == NULL)
{
printf("Unable to allocate space for student\n\n");
exit (EXIT_FAILURE);
}
if ((f = fopen("sort.txt", "r")) == NULL)
{
printf("Error, the file cannot be opened\n");
}
i = 0;
while (!feof(f)) {
fflush(stdin);
fgets(student_info[i].line, 200, f);
i++;
}
fclose (f);
printf("\n\n%s%6s%20s%17s\n", "ID", "NAME", "TERM", "GPA");
student_info_compare();
for(i = 0; i < max; i++)
{
// iwant to sort here
qsort(student_info, max, sizeof student_info[0], student_info_compare);
puts(student_info[i].line);
}
free(student_info);
student_info = NULL;
}
Try this:
static int student_info_compare(const void *a, const void *b)
{
const student_info *sia = a, *sib = b;
return strcmp(sia->name, sib->name);
}
then add this before the print loop:
qsort(student_info, max, sizeof student_info[0], student_info_compare);
This uses the standard qsort() function to sort the array. The student_info_compare() function serves as the comparison-callback, since qsort() doesn't know how your data looks.
The arguments to the comparison-callback have type const void *, which basically means "here's a pointer to something whose exact type is not known, and you're supposed to treat it as a read-only pointer". That's how qsort() passes pointers to the array elements, since (again) it doesn't know that they are of type const student_info *.

Resources