Hey guys i have this c program working and i want to modify the printbooking() in order to print only rooms with a status of "checked-out"
so far i am only getting an error about comparison between pointer and integer....any help on how i should do this?
and also. i want to be able to search through rooms with the roomID and edit their details.Any help will be appreciated!
Here is my code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char BookId[7];
char CustId[7];
char RoomId[5];
char NumGuests[4];
char StartDate[11];
char EndDate[11];
char Status[20];
} booking_t;
int readBooking(booking_t *myStruct)
{
FILE *infile;
infile = fopen("booking.txt", "r");
char record[201];
char *token;
int i = 0;
while (fgets(record, 200, infile) != NULL) {
token = strtok(record, ";");
strcpy(myStruct[i].BookId, token);
token = strtok(NULL, ";");
strcpy(myStruct[i].CustId, token);
token = strtok(NULL, ";");
strcpy(myStruct[i].RoomId, token);
token = strtok(NULL, ";");
strcpy(myStruct[i].NumGuests, token);
token = strtok(NULL, ";");
strcpy(myStruct[i].StartDate, token);
token = strtok(NULL, ";");
strcpy(myStruct[i].EndDate, token);
token = strtok(NULL, "\n");
strcpy(myStruct[i].Status, token);
i++;
}
fclose(infile);
return(i);
}
//this is the code that i want to print out only "checked out rooms"
void printBooking(booking_t *myStruct, int Size)
{
printf("Booking ID, Customer ID, Room ID, Number of Guests, Start Date, End Date, Status\n");
int i;
for(i = 0; i < Size;i++){
if(myStruct[i].Status[15] == "checked-out") //the error message points to this line
printf("%s %s %s %s %s %s %s\n", myStruct[i].BookId, myStruct[i].CustId, myStruct[i].RoomId, myStruct[i].NumGuests, myStruct[i].StartDate, myStruct[i].EndDate, myStruct[i].Status);
}
printf("\n");
}
//
void printMayBooking(booking_t *myStruct, int Size)
{
printf("Booking ID, Customer ID, Room ID, Number of Guests, Start Date, End Date, Status\n");
int i;
for(i = 0; i < Size;i++){
if(myStruct[i].StartDate[4] == '5')
printf("%s %s %s %s %s %s %s\n", myStruct[i].BookId, myStruct[i].CustId, myStruct[i].RoomId, myStruct[i].NumGuests, myStruct[i].StartDate, myStruct[i].EndDate, myStruct[i].Status);
}
printf("\n");
}
int main()
{
booking_t booking_list[50];
int Size;
Size = readBooking(booking_list);
printBooking(booking_list, Size);
printMayBooking(booking_list, Size);
return(0);
}
if(myStruct[i].Status[15] == "checked-out")
myStruct[i].Status[15] gives the character at that index and you are comparing it with a string which is what the problem is.
I think you need to compare with the Status array itself using strcmp.
if( strcmp( myStruct[i].Status, "checked-out") == 0 )
// ...
Status[15] is a char, and you're trying to compare to the const char * "checked-out". I don't know what the "15" is for, but I suspect you just want
if(strcmp(myStruct[i].Status, "checked-out") == 0)
strcmp() is the string comparison function in C.
Related
I have to write this code, I mean I should read from the file name of students and their mark, and then sort students by the grow of mark. Now I just want to output only mark. I want to display grades using structures. I don't know where the problem is.
text.file
Jon 3
Alina 5
Ron 1
#include <stdio.h>
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdlib.h>
int main()
{
const int N = 3;
int i = 0;
struct student {
char surname[50];
int mark;
};
struct student PI1[N];
char str[50];
const char s[1] = " ";
char* token;
FILE* ptr;
token = strtok(str, s);
ptr = fopen("test.txt", "r");
if (NULL == ptr) {
printf("file can't be opened \n");
}
while (fgets(str, 50, ptr) != NULL){
token = strtok(str, s);
strcpy(PI1[i].surname, token);
token = strtok(NULL, s);
PI1[i].mark = atoi(token);
i++;
}
fclose(ptr);
printf("The marks is:\n");
printf("%d %d %d", PI1[0].mark, PI1[1].mark, PI1[2].mark);
return 0;
}
You need to prevent the program from reading from the file pointer if opening the file fails:
ptr = fopen("test.txt", "r");
if (NULL == ptr) {
perror("test.txt");
return 1; // this could be one way
}
The second argument to strok should be a null terminated string. const char s[1] = " "; only has room for one character. No null terminator (\0). Make it:
const char s[] = " "; // or const char s[2] = " "; or const char *s = " ";
Don't iterate out of bounds. You need to check so that you don't try to put data in PI1[N] etc.
while (i < N && fgets(str, sizeof str, ptr) != NULL) {
// ^^^^^^^^
Check that strok actually returns a pointer to a new token. If it doesn't, the line you've read doesn't fulfill the requirements.
while (i < N && fgets(str, sizeof str, ptr) != NULL) {
token = strtok(str, s);
if(!token) break; // token check
strcpy(PI1[i].surname, token);
token = strtok(NULL, s);
if (token) // token check
PI1[i].mark = atoi(token);
else
break;
i++;
}
You could also skip the strcpy by reading directly into your struct student since char str[50]; has the same length as surname. str should probably be larger though, but for now:
while (i < N && fgets(PI1[i].surname, sizeof PI1[i].surname, ptr) != NULL) {
token = strtok(PI1[i].surname, s);
if(!token) break;
token = strtok(NULL, s);
if (token)
PI1[i].mark = atoi(token);
else
break;
i++;
}
Only print as many marks as you successfully read
printf("The marks are:\n");
for(int idx = 0; idx < i; ++idx) {
printf("%d ", PI1[idx].mark);
}
putchar('\n');
Having trouble using malloc to create each row vector to store data in. Also, I can't seem to assign the fields of struct using functions I've coded.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "redo_hw4_functs.h"
typedef struct _Stores{
char name[10];
char addr[50];
char city[30];
char state[3];
} Store;
//function that creates a new matrix of size r x c
int main(int argc, char* argv[])
{
Store* pStores;
FILE* pFile;
char* stateGiven;
char buffer[180];
char* storeGiven;
char lineChar;
int lineNumb = 0;
int r;
char* tempName, tempAddr, tempCity, tempState;
if(argc < 4){
printf("Too few arguments! \n");
}
else if(argc > 4){
printf("Too many arguments! \n");
}
pFile = fopen(argv[1],"r");
for (lineChar = getc(pFile); lineChar != EOF; lineChar = getc(pFile))
{
if (lineChar == '\n') // Increment count if this character is newline
lineNumb = lineNumb + 1;
}
fclose(pFile);
pFile = fopen(argv[1],"r");
while(fgets(buffer, sizeof(buffer), pFile) != NULL)
{
for (r = 0; r < lineNumb; r++)
{
pStores = realloc(pStores, lineNumb * sizeof(Store*));
Store pStores[r] = malloc(sizeof(Store));
getName(pStores[r].name, buffer);
getAddress(pStores[r].addr, buffer);
getCity(pStores[r].city, buffer);
getState(pStores[r].state, buffer);
printf(" Store name: %s \n", pStores[r].name);
printf(" Address: %s \n", pStores[r].addr);
printf(" City: %s \n", pStores[r].city);
printf(" State: %s \n", pStores[r].state);
}
}
}
^^^ In the above block of code I made some improvements and also included realloc(). I initialized the lineNumb variable. I believe the problem regarding my initialization of each row that Store* pStores is trying to reference/point to.
Here are the helper functions:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "redo_hw4_functs.h"
//accepts a line of string formatted as expected and stores the store name in char file
void getName(char strName[], char strLine[])
{
char* token;
char delim[] = " ,\t\n";
token = strtok(strLine, delim);
while(token != NULL)
{
if(strcmp(token, "sears") == 0 || strcmp(token, "kmart"))
{
strcpy(strName, token);
break;
}
token = strtok(NULL, delim);
}
}
//accepts a line of string formatted as expected and stores the store address in char file
void getAddress(char strAddress[], char strLine[])
{
char* token;
char delim[] = ",\t\n";
token = strtok(strLine, delim);
while(token != NULL)
{
if(isdigit(token[0]) && isalpha(token[sizeof(token)-1]))
{
strcpy(strAddress, token);
break;
}
token = strtok(NULL, delim);
}
}
//accepts a line of string formatted as expected and stores the store city in char file
void getCity(char strCity[], char strLine[])
{
int i;
char* token;
char delim[] = ",\t\n";
token = strtok(strLine, delim);
while( token != NULL )
{
strcpy(strCity, token + strlen(token)-3);
token = strtok(NULL, delim);
}
}
//accepts a line of string formatted as expected and stores the store state in char file ¡OJO! This is the hardest one because you cant rely on delimeters alone to find state
void getState(char strState[], char strLine[])
{
int i;
char* token;
char delim[] = "\n";
token = strtok(strLine, delim);
while( token != NULL )
{
strcpy(strState, token + strlen(token)-3);
token = strtok(NULL, delim);
}
}
Here is some sample input:
Kmart, 217 Forks Of River Pkwy, Sevierville TN
Kmart, 4110 E Sprague Ave, Spokane WA
Kmart, 1450 Summit Avenue, Oconomowoc WI
Sears, 2050 Southgate Rd, Colorado Spgs CO
Sears, 1650 Briargate Blvd, Colorado Spgs CO
Sears, 3201 Dillon Dr, Pueblo CO
I'm not sure where I'm messing up so I've given a summary of each function so my logic can be checked!
The main program takes arguments from the command line and stores them in char pointer array.
The correct command to run program is ./re-do_hw4_prob6 filename. (filename is sears_kmart_stores_closing_2019.txt in this case)
After checking if argument number is correct, the file is opened.
A while loop copies strings of text from file to buffer until NULL is met.
Then the function getState() is called. The state is printed.
The file is closed.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "redo_hw4_functs.h"
int main(int argc, char* argv[])
{
char** states;
FILE* pFile;
char buffer[80];
int i = 0;
if(argc < 2){
printf("Too few arguments! \n");
}
else if(argc > 2){
printf("Too many arguments! \n");
}
pFile = fopen(argv[1], "r");
states = malloc(50*sizeof(char));
for (i = 0; i < 50; i++)
{
states[i] = malloc(3*sizeof(char));
while(fgets(buffer, sizeof(buffer), pFile) != NULL)
{
getState(states[i], buffer);
printf("State: %s \n", states[i]);
}
}
fclose(pFile);
}
The getState() function takes in two char arrays. One to read from the other to copy too.
It tokenizes the string being read from using a comma, a tab, and a new line as the delimiters. -> ",\t\n"
On the last token it copies the last two chars to the empty string array.
//accepts a line of string formatted as expected and stores the store state in char file ¡OJO! This is the hardest one because you cant rely on delimeters alone to find state
void getState(char strState[], char strLine[])
{
int i;
char* token;
char delim[] = ",\t\n";
token = strtok(strLine, delim);
token = strtok(strLine, delim);
token = strtok(strLine, delim);
for(i = (strlen(token) - 2); i < strlen(token); i++)
{
strState[i] =token[i];
}
}
I have also included my other functions to see if there are any other mistakes to be corrected.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "redo_hw4_functs.h"
//accepts a line of string formatted as expected and stores the store name in char file
void getName(char strName[], char strLine[])
{
char* token;
char delim[] = " ,\t\n";
token = strtok(strLine, delim);
while(token != NULL)
{
if(strcmp(token, "sears") == 0 || strcmp(token, "kmart"))
{
strcpy(strName, token);
break;
}
token = strtok(NULL, delim);
}
}
//accepts a line of string formatted as expected and stores the store address in char file
void getAddress(char strAddress[], char strLine[])
{
char* token;
char delim[] = ",\t\n";
token = strtok(strLine, delim);
while(token != NULL)
{
if(isdigit(token[0]) && isalpha(token[sizeof(token)-1]))
{
strcpy(strAddress, token);
break;
}
token = strtok(NULL, delim);
}
}
//accepts a line of string formatted as expected and stores the store city in char file
void getCity(char strCity[], char strLine[])
{
int i;
char* token;
char delim[] = ",\t\n";
token = strtok(strLine, delim);
token = strtok(strLine, delim);
token = strtok(strLine, delim);
for(i = 0; i < (strlen(token) - 3); i++)
{
strcpy(strCity[i], token[i]);
}
}
//accepts a line of string formatted as expected and stores the store state in char file ¡OJO! This is the hardest one because you cant rely on delimeters alone to find state
void getState(char strState[], char strLine)
{
int i;
char* token;
char delim[] = ",\t\n";
token = strtok(strLine, delim);
token = strtok(strLine, delim);
token = strtok(strLine, delim);
for(i = (strlen(token) - 2); i < strlen(token); i++)
{
strcpy(strState[i], token[i]);
}
}
Here is an example of input text that is to be read:
Kmart, 217 Forks Of River Pkwy, Sevierville TN
Kmart, 4110 E Sprague Ave, Spokane WA
Kmart, 1450 Summit Avenue, Oconomowoc WI
Sears, 2050 Southgate Rd, Colorado Spgs CO
Sears, 1650 Briargate Blvd, Colorado Spgs CO
Sears, 3201 Dillon Dr, Pueblo CO
Here is an example of what the program is expected to be outputting:
State:TN
State:WA
State:WI
State:CO
State:CO
State:CO
Here is an example of what the program is outputting:
I assume that you want not only the status but also all the other fields so that you can deal with them later.
The code below may be quite different from yours, but I think that it is easier to use a single function to read each record.
The function read_data() reads data from the file pointer fp and store them in data, which is a pointer to a predefined struct data_t.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 1024
typedef struct {
char name[64];
char addr[64];
char city[64];
char state[8];
} data_t;
int read_data(FILE *fp, data_t *data) {
char buffer[BUFFER_SIZE];
// Read a record. If end-of-file is read, return -1.
if (fgets(buffer, BUFFER_SIZE, fp) == NULL) {
return -1;
}
char delim[] = ",\t\n";
// Find the name of the record.
char *token = strtok(buffer, delim);
strcpy(data->name, token);
// Find the address of the record.
token = strtok(NULL, delim);
while (*token == ' ') {
++token;
}
strcpy(data->addr, token);
// Find the city and status of the record.
// We cannot split them by strtok() easily, so we handle it later.
token = strtok(NULL, delim);
while (*token == ' ') {
++token;
}
// Find the position of the state.
char *ptr = token;
while (*ptr != '\0') {
++ptr;
}
ptr -= 2;
strcpy(data->state, ptr);
// Use NULL to separate the city and the state so that we can use strcpy().
while (*(ptr - 1) == ' ') {
--ptr;
}
*ptr = '\0';
// Copy the city field.
strcpy(data->city, token);
return 0;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "The number of arguments is incorrect.\n");
fprintf(stderr, "Usage: %s filename\n", argv[0]);
return -1;
}
FILE *fp = fopen(argv[1], "r");
data_t *data = malloc(sizeof(data_t));
while (read_data(fp, data) == 0) {
printf("State: %s\n", data->state);
}
free(data);
fclose(fp);
return 0;
}
The way to read data is hard-coded, so if the input format is different, you may need to change the content of read_data(), but it works well for your sample input.
I'm writing a basic program that takes a CSV file, prints the first field, and does some numerical evaluation of the other fields.
I'm looking to put all the numerical fields into an array but every time I do this and try to access a random element of the array, it prints the entire thing
My CSV file is:
Exp1,10,12,13
Exp2,15,16,19
and i'm trying to access the second field so it prints
Exp1 12
Exp2 16
but instead I'm getting
Exp1 101213
Exp2 151619
If someone could provide some suggestions. This is my code:
#define DELIM ","
int main(int argc, char *argv[])
{
if(argc == 2) {
FILE *txt_file;
txt_file = fopen(argv[1], "rt");
if(!txt_file) {
printf("File does not exist.\n");
return 1;
}
char tmp[4096];
char data[4096];
char expName[100];
char *tok;
int i;
while(1){
if(!fgets(tmp, sizeof(tmp), txt_file)) break;
//prints the experiment name
tok = strtok(tmp, DELIM);
strncpy(expName, tok, sizeof(expName));
printf("\n%s ", expName);
while(tok != NULL) {
tok = strtok(NULL, DELIM);
//puts data fields into an array
for(i=0; i < sizeof(data); i++) {
if(tok != NULL) {
data[i] = atoi(tok);
}
}
printf("%d", data[1]);
}
}
fclose(txt_file);
return 0;
}
sample to fix
char tmp[4096];
int data[2048];
char expName[100];
char *tok;
int i=0;
while(fgets(tmp, sizeof(tmp), txt_file)){
tok = strtok(tmp, DELIM);
strncpy(expName, tok, sizeof(expName));
printf("\n%s ", expName);
while((tok = strtok(NULL, DELIM))!=NULL){
data[i++] = atoi(tok);
}
printf("%d", data[1]);
i = 0;
}
A modified code snippet:
int data[20]; // change 20 to a reasonable value
...
while (1)
{ if (!fgets(tmp, sizeof(tmp), txt_file))
break;
//prints the experiment name
tok = strtok(tmp, DELIM);
strncpy(expName, tok, sizeof(expName));
printf("\n%s ", expName);
i = 0;
tok = strtok(NULL, DELIM);
while (tok != NULL)
{ //puts data fields into an array
data[i++] = atoi(tok);
if (i == 20)
break;
tok = strtok(NULL, DELIM);
}
if (i > 1)
printf("%d", data[1]);
}
Does anyone know why my program doesn't read from my delimited file? I thought it would print everything from my delimited file after the program ran through my printPropertyListing() method at the bottom but instead it gives me the error message warning "warning: comparison between pointer and integer". It's telling me the error is on the beginning line of my for loop in the main method. Any solutions please?
Here is what my delimited file looks like:
123 Cherry Tree Drive#330#Condo#2#1#275900#Toronto#
14 Leaside Lane#N/A#House#4#2#445500#Brampton#
2478 Waterfront Avenue#N/A#House#5#3#899900#Mississauga#
7 Lucky Lane#1206#Condo#3#2#310000#Toronto#
51 West Street#32#Townhouse#4#2#450000#Brampton#
193 Crystal Road#1519#Condo#1#1#250750#Toronto#
3914 Tangerine Terrace#N/A#House#3#1#427750#Mississauga#
10 Redding Road#N/A#House#4#2#512350#Toronto#
76 Old School Avenue#227#Townhouse#3#2#475000#Toronto#
90 Brookhaven Terrace#N/A#House#4#2#512750#Brampton#
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char buildingType[10];
int numBedrooms;
int numBathrooms;
}Propertylisting;
typedef struct {
Propertylisting propertylisting;
char address[100];
char unitNum [10];
char city [50];
int listPrice;
} Listing;
void parseListings(FILE *in, Listing listing[], int arraySize);
void printPropertyListing(Listing l);
int main()
{
Listing listing[10];
FILE *fp = fopen("PropertyListings.txt", "r");
if (fp == NULL)
{
printf("Could not open file!");
exit(1);
}
else
{
parseListings(fp, listing, 10);
if (listing == 0)
{
printf("No Property data found.");
exit(1);
}
printf("\nNumber of listings in file: %d\n\n", listing);
int i;
for (i = 0; i < listing; i++)
{
printPropertyListing(listing[i]);
printf("\n");
}
fclose(fp);
}
return 0;
}
void parseListings(FILE *in, Listing listing[], int arraySize)
{
// Holds the current index of the Listing array
int n = 0;
// Set value as empty string
char line[256];
// A token pointer that the strtok() function returns
char *token;
char *delimiter = "#";
while (!feof(in)&& n > arraySize)
{
fgets(line, 256, in);
// Read the address
token = strtok(line, delimiter);
strcpy(listing[n].address, token);
// Read the unitNum
token = strtok(NULL, delimiter);
strcpy(listing[n].unitNum, token);
// Read the building typede
token = strtok(NULL, delimiter);
strcpy(listing[n].propertylisting.buildingType, token);
token = strtok(NULL, delimiter);
int numBedrooms = strtol(token, NULL, 10);
listing[n].propertylisting.numBedrooms = numBedrooms;
token = strtok(NULL, delimiter);
int numBathrooms = strtol(token, NULL, 10);
listing[n].propertylisting.numBathrooms = numBathrooms;
token = strtok(NULL, delimiter);
int listPrice = strtol(token, NULL, 10);
listing[n].listPrice = listPrice;
token = strtok(NULL, delimiter);
strcpy(listing[n].city, token);
n++;
}
return n;
}
void printPropertyListing(Listing l)
{
printf("%s %s %s\n%s %d %d %d\n\n",
l.address,
l.unitNum,
l.city,
l.propertylisting.buildingType,
l.propertylisting.numBedrooms,
l.propertylisting.numBathrooms,
l.listPrice);
}
The problem is in your for loop:
for (i = 0; i < listing; i++)
i is of type int and listing is of type Listing [10];
As pointed out by others, your listing variable is an array (which is actually a pointer to the start of a block of memory being used as an array). This means you are attempting to compare a pointer to an int, which does not make sense.
It looks like you are trying to compare to the size of the array, and since your parseListings function already returns the number of listings it has parsed, you can instead do the following:
int numListings = parseListings(fp, listing, 10);
if (numListings == 0) {
printf("No Property data found.");
exit(1);
}
printf("\nNumber of listings in file: %d\n\n", numListings);
int i;
for (i = 0; i < numListings; i++) {
printPropertyListing(listing[i]);
printf("\n");
}
You will note that I changed a few other locations where you were also using the listing variable, but I suspect you had wanted to check against the number of listings.
In addition to this, there is the points which Jens made about other bugs in your program, which would make this the perfect time to learn about the while 1: ... break; paradigm.
while (n < arraySize) {
fgets(line, 256, in);
if(feof(in)) {
break;
}
Credit to other people for pointing out all of these bugs; I have just attempted to formulate all of their responses into a single coherent guide to things you should consider for improving this code specifically and all of your code in general.
Edit: additionally, the return type of parseListing should be changed to int in order to match the fact that you return n;