array value over write - c

hello every one i am facing a strange problem i my code i am reading values from the file and file has rows and columns i am storing the second column in my array
but the problem i that when i first time copy in my position encryption[0] = token
i works well when i store at position encryption [1] my encryption [0] value over write with and become the same as encryption[1] the again at third loop encryption [0] ,encryption [1] become same as encryption [2] so in the end all values become the last sored value
here is my code kingly help me
#include<stdio.h>
#include <sys/stat.h>
#include<time.h>
#include<string.h>
void main()
{
FILE * f1 = fopen("2.19.18.110_202.142.175.104.csv" , "r");
if(f1==NULL)
{
printf("not open");
}
char ch;
int row =0;
int col=0;
while(ch!=EOF)
{
ch = fgetc(f1);
if(ch=='\n')
row++;
if(ch==' ')
col++;
}
fclose(f1);
int b=0;
int gg=0;
//for( b=0;b<row;b++)
char * encryption[row];
char payload[col*10];
FILE * f2 = fopen("2.19.18.110_202.142.175.104.csv" , "r");
while( fgets ( payload, sizeof payload, f2)!=NULL)
{
int col1=0;
printf("b= %d\t" , b);
// fgets ( payload, sizeof payload, f2);
fputs(payload ,stdout);
printf("\n\n");
char *token;
token = strtok(payload, " ");
token = strtok(NULL, " ");
encryption[gg] = token;
printf("token %s\n" ,token);
gg=gg+1;
printf("encryption %s\n" ,encryption[0]);
printf("encryption %s\n" ,encryption[1]);
printf("encryption %s\n" ,encryption[2]);
printf("encryption %s\n" ,encryption[3]);
token = strtok(NULL, " ");
while ( token != NULL)
{
token = strtok(NULL, " ");
}
}
}

encryption[] is just an array of pointers - for each element you need to malloc() sufficient memory (strlen(token) + 1 bytes) and then use strcpy() to copy the string contents from token to encryption[gg].
Change:
token = strtok(NULL, " ");
encryption[gg] = token;
to:
token = strtok(NULL, " ");
encryption[gg] = malloc(strlen(token) + 1);
strcpy(encryption[gg], token);
Don't forget to free() each element of encryption later when you're done, otherwise you'll leak memory.

Related

How to read from the file and write it in the structure? I have a little trouble with my code

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');

Error when reading strings from CSV (Core Dumped)

I keep getting the same error, I'm new to programming so I'm not so sure if the Syntax is correct.
Every time I run it, it returns Segmentation Fault(core dumped), I'm not even sure If I can open a file with a string (address) instead of the filename in extense.
Also the files I'm reading from are CSV but in txt format.
I'm using C99
#define BUFFER_SIZE 1024
#define TAM_PERGUNTAS 128
struct question{
char category[TAM_PERGUNTAS];
char question[TAM_PERGUNTAS];
char option1[TAM_PERGUNTAS];
char option2[TAM_PERGUNTAS];
char option3[TAM_PERGUNTAS];
char correct[TAM_PERGUNTAS];
};
struct question vec_question[BUFFER_SIZE];
void questions() {
FILE *perguntas;
int numaleat=0;
int num_questions, counter = 0, index, temp_randomizer=0;
char line[BUFFER_SIZE];
char answer[32];
char address[TAM_PERGUNTAS];
address[0] = '\0';
srand(time(NULL));
printf("Digite agora o numero de perguntas desejadas.(MAX 20) : "); //Insert Number of questions
scanf("%d", &num_questions);
printf("\n");
for (counter = 0; counter < num_questions; counter++) {
temp_randomizer = rand() % j; //j Represents the number o CATEGORIES at play and acts as a marker in the SELECTION string
sprintf(address, "%s.txt", SELECTION[temp_randomizer]);
perguntas = fopen(address, "r");
if (perguntas == NULL) {
printf("ERROR OPENING FILE!");
}
index = 0;
while (fgets(line, sizeof(line), perguntas) != NULL) {
strcpy(vec_question[index].category, strtok(line, ";"));
strcpy(vec_question[index].question, strtok(NULL, ";"));
strcpy(vec_question[index].option1, strtok(NULL, ";"));
strcpy(vec_question[index].option2, strtok(NULL, ";"));
strcpy(vec_question[index].option3, strtok(NULL, ";"));
strcpy(vec_question[index].correct, strtok(NULL, ";"));
vec_question[index].correct[strlen(vec_question[index].correct) - 1] = '\0';
index++;
}
fclose(perguntas);
index = 20;
numaleat = rand() % index;
printf("%s : %s\n%s\n%s\n%s",vec_question[numaleat].category,vec_question[numaleat].question,vec_question[numaleat].option1,vec_question[numaleat].option2,vec_question[numaleat].option3);
for (int i = 0; i < num_users; i++) {
printf("\n%s: ", &users[i][20]);
scanf("%s", &answer[32]);
if (answer == vec_question[numaleat].correct)
userspoints[i] += 1;
}
}
}
In general one should assume that functions like strtok can fail.
Sometimes it fails and returns a NULL value. A short record in your input is a likely cause.
Consider using it with a loop, and breaking out of the loop once strtok returns NULL.
I found a simple example here.
#include <string.h>
#include <stdio.h>
int main () {
char str[80] = "This is - www.tutorialspoint.com - website";
const char s[2] = "-";
char *token;
/* get the first token */
token = strtok(str, s);
/* walk through other tokens */
while( token != NULL ) {
printf( " %s\n", token );
token = strtok(NULL, s);
}
return(0);
}
Note that it does one strtok to get the first token. That might return NULL in which case the loop doesn't run. If it doesn't return NULL then it prints that token, and asks strtok for the next token. It keeps doing that until strtok returns NULL.

Removing a word from a given string

I have been trying to write a code to remove a word from an inputted string as part of my homework. But the thing is the outputted "modified" string never really gets modified and it actually always outputs the inputted string. I'm new to strings so I don't have a perfect understanding of how the string.h library functions work.
#include<stdio.h>
#include<string.h>
int main(void)
{
char str[60], strtemp[60], word[10], * token;
printf("Enter the sentence: ");
gets_s(str);
printf("Enter the word to be deleted: ");
gets_s(word);
int i = 0;
token = strtok(str, " ");
while (token != NULL) {
if (!i && token != word)
strcpy(strtemp, token);
else if (token == word) {
token = strtok(NULL, " ");
continue;
}
else {
strcat(strtemp, " ");
strcat(strtemp, token);
}
token = strtok(NULL, " ");
i++;
}
strcpy(str, strtemp);
printf("Modified string: %s \n", str);
}
Add the following:
char *strremove(char *str, const char *sub) {
size_t len = strlen(sub);
if (len > 0) {
char *p = str;
while ((p = strstr(p, sub)) != NULL) {
memmove(p, p + len, strlen(p + len) + 1);
}
}
return str;
}
You should use the memmove() (written on your post's comment too.)
Reference: this thread of SO.

How to fix 'strtok destroy original string' in c

I'm writing a compiler for assembler, and I need to do parsing to the text I get from a file, without making any changes in the original String. The function I used to copy the String was strcpyto a buffer, and to cut the String was strtok to cut the buffer.
Everything works perfect, but once I try to cut the original String after using the function addressingConstantIndex , I get null.
I tried to change the type of the buffer to a pointer of Character, it didn't really work. I guess the main problem it's in the way I copy the original String to the buffer.
int main(){
char desti[MAXCHAR];
char *temp;
char *token;
temp = "mov LIST[5] , r4";
strcpy(desti,temp);
printf("\ndest is : %s\n", desti);
token = strtok(desti," ");
printf("\nthe Token in Main is : %s \n", token);
token = strtok(NULL, ",");
printf("\nthe Token in Main is : %s\n", token);
printf("\nThe value is %d \n ",addressingConstantIndex(token));
token = strtok(NULL, " ,");
printf("\nthe Token in Main is : %s\n", token);
return 0;
}
int addressingConstantIndex(char * str) {
char buf[43];
char *token;
int ans;
strcpy(buf, str);
token = strtok(buf, "[");
printf("The string is %s\n",str);
if (token != NULL)
{
printf("the token is %s\n", token);
token = strtok(NULL, "]");
printf("the token is %s\n", token);
if(isOnlyNumber(token))
{
token = strtok(NULL, " ");
if (checkIfSpaces(token,0) == ERROR)
{
printf("ERROR: Extra characters after last bracket %s \n", str);
ans = ERROR;
} else
ans = OK;
} else {
printf("ERROR: Unknown string - %s - its not a macro & not a number.\n", token);
ans = ERROR;
}
} else {
printf("ERROR: %s , its not a LABEL", token);
ans = ERROR;
}
return ans;
}
int isOnlyNumber(char *str) {
int i, isNumber;
i = 0;
isNumber = 1;
if (!isdigit(str[i]) && !(str[i] == '-' || str[i] == '+'))
{
isNumber = ERROR;
}
i++;
while (i < strlen(str) && isNumber == 1)
{
if (!(isdigit(str[i]))) {
if (isspace(str[i]))
isNumber = checkIfSpaces(str, i);
else
isNumber = ERROR;
}
i++;
}
return isNumber;
}
int checkIfSpaces(char *str, int index) {
int i;
if (str == NULL)
{
return OK;
} else {
for (i = index; i < strlen(str); i++)
{
if (!isspace(str[i])) return ERROR;
}
}
return OK;
}
The expecting result:
dest is : mov LIST[5] , r4
the Token in Main is : mov
the Token in Main is : LIST[5]
The string is LIST[5]
the token is LIST
the token is 5
The value is 1
the Token in Main is : r4
The real result:
dest is : mov LIST[5] , r4
the Token in Main is : mov
the Token in Main is : LIST[5]
The string is LIST[5]
the token is LIST
the token is 5
The value is 1
the Token in Main is : (null)
The difference It's in the last row of the result.
The problem is that strtok() maintains a single static pointer to the current string location. So in addressingConstantIndex(), you start processing the local buf, so that when you return to main() it is no longer parsing desti but the now out of scope buf from addressingConstantIndex().
The simplest change to your existing code would be to use strtok_r() (or strtok_s() on Windows):
char* context = 0 ;
token = strtok_r( desti, " ", &context ) ;
printf("\nthe Token in Main is : %s \n", token);
token = strtok_r( NULL, ",", &context ) ;
...
Then similarly in addressingConstantIndex():
char* context = 0 ;
token = strtok_r(buf, "[", &context);
...
strtok replaces the separator in the string with a NULL on each call. Your code is finding the 'LIST[5]' token at the main level, at which point it has replaced the ',' with a NULL.
In addressingConstantIndex, strtok is reset with a new string and parses correctly (though your function is typed void instead of int).
At at the main level again, strtok is not being reset, so it is continuing to parse the string used in addressingConstantIndex.
To fix this you need to reset strtok again to continue. However you can't just call it with strtok(desti,",") as the desti has all the separators set to NULL from previous calls.
A quick solution is to copy the token to feed into addressingConstantIndex at the main level, and complete the main level before parsing at the next level.
int main(){
char desti[MAXCHAR];
char *temp;
char *token;
temp = "mov LIST[5] , r4";
strcpy(desti,temp);
printf("\ndest is : %s\n", desti);
token = strtok(desti," ");
printf("\nMnemonic : %s \n", token);
token = strtok(NULL, ",");
printf("\nLIst bit: %s\n", token);
char buf[80]; //Save the token
strcpy(buf, token);
token = strtok(NULL, " ,"); //Finish this level of processing
printf("\nRegister: %s\n", token);
//Continue at the next level with copy
printf("\nThe value is %d \n ",addressingConstantIndex(buf));
return 0;
}
Though a strtok_r solution might suit your needs better going forward

comparison between pointer and integer error

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.

Resources