I am doing a project which involves using .csv files handling in c. I have been bothered with this question and can't find a solution, I want to know how to edit/ update my csv file.
My csv file is something like:
Username, Pin, Balance
Right now I am able to get the contents of the csv file, but I am struggling on how to update the contents.
I want to make it so that a username can change its pin, so basically changing the value at pin to be something else.
After reading the comments I have tried the replacing method, it goes like this.
void change_pin(char *C){
char line[200];
char user[50];
char date[50];
char action[50];
char user_n[50];
char date_n[50];
char action_n[50];
FILE *str = fopen("Example.csv", "r+");
FILE *new = fopen("new.csv", "w");
if (str == NULL) {
printf("Error opening file");
fclose(str);}
if (new == NULL) {
printf("Error opening file");
fclose(new);}
while(fgets(line, 200, str)){
char *token;
token = strtok(line, ",");
while (token != NULL){
if (strcmp(token, C) == 0){
strcpy(user, token);
token = strtok(NULL, ",");
strcpy(date, token);
token = strtok(NULL, ",");
strcpy(action, token);
token = strtok(NULL, ",");
strcpy(date, C);
fprintf(new, "%s,%s,%s\n", user, date, action);
}
else{
strcpy(user_n, token);
token = strtok(NULL, ",");
strcpy(date_n, token);
token = strtok(NULL, ",");
strcpy(action_n, token);
token = strtok(NULL, ",");
fprintf(new, "%s,%s,%s\n", user_n, date_n, action_n);
}
}
}
remove("Example.csv");
rename("new.csv", "Example.csv");
fclose(str);
fclose(new);
}
The strcpy (date, C) is just for testing
This works!, but the problem is it doesn't work the second time, I don't know why, when I want to do it the second time it gives a error.
I got it to work now just by removing the '\n' in fprintf. Thank you everyone for helping me out
Related
I have a char array (buf) that exists out of multiple lines and each line is split up by multiple tabs. I want to separate this. I use the following code for this:
char copy[4096];
char* split_request = strtok(buf, "\r\n");
strcpy(copy, split_request);
while(split_request != NULL) {
if (strchr(copy, '\t') != NULL) {
printf("We have a tab");
//If I uncomment this line I get an assertion error
//char* temp = strtok(copy, '\t');
}
printf(split_request);
split_request = strtok(NULL, "\r\n");
if (split_request != NULL) {
strcpy(copy, split_request);
}
printf("\n");
}
If I uncomment that one line of code, only the first line is processed. In addition, it is printed 5 times, and each time one tabbed column disappears. It feels like despite the strcpy, the original string is still affected...
I was experimenting with an alternative approach to your problem. I have used strtok_r for separating lines and each line is processed using strtok for tabs. The code is given below.
void lineParser(char *singleLine){
const char tab[] = "\t";
char *token = NULL;
if(strchr(singleLine, '\t') != NULL){
token = strtok(singleLine, tab);
while(token != NULL){
printf("%s\n", token);
token = strtok(NULL, tab);
}
}
}
int main()
{
char buf[] = "Stack\tOverFlow\r\nStack\tExchange\r\n";
char *rest = buf;;
char* token = NULL;
const char tab[] = "\t";
const char newline[] = "\r\n";
while ((token = strtok_r(rest, " ", &rest))) {
lineParser(token);
token = strtok_r(rest, newline, &rest);
}
}
My code looks like that:
char *token;
token = strtok(myStrings, delimiter);
char newArray[MAXCHARS];
while (token != NULL) {
printf("%s\n", token);
strcpy(newArray, &token);
token = strtok(NULL, delimiter);
}
I want to add the token to my char array but it doesn't work.
It prints the right token (e.g. Martin) but I can't add it to my char array.
I have tried using a function that would work in "regular" c:
const char* getfield(char* line, int num)
{
const char* tok;
for (tok = strtok(line, ";");
tok && *tok;
tok = strtok(NULL, ";\n"))
{
if (!--num)
return tok;
}
return NULL;
}
int main()
{
FILE* stream = fopen("v1.csv", "r");
char line[1024];
while (fgets(line, 1024, stdin))
{
char* tmp = strdup(line);
printf("Field 3 would be %s\n", getfield(tmp, 3));
// NOTE strtok clobbers tmp
free(tmp);
}
}
I am trying to read a file names "v1.csv" located in my pebble app resources folder.
You can not read/write to files, use file descriptor or any of the f* functions in the Pebble SDK.
If you want to store data on the watch, you should look into the Persistent Storage API.
I've used strdup() in the past in the same way that I am using it here. I am passing token2 into strdup which is of type char * with a valid pointer in it, yet when I try to run the line "name = strdup(token2);" my program segfaults and I am quite unsure as to why. If anyone would be able to help me it would be greatly appreciated. I also realize that my code does not return a proper type yet, I am still working on writing all of it.
struct YelpDataBST* create_business_bst(const char* businesses_path, const char* reviews_path){
if(fopen(businesses_path,"r") == NULL || fopen(reviews_path,"r") == NULL)
return NULL;
FILE* fp_bp = fopen(businesses_path, "r");
FILE* fp_rp = fopen(reviews_path, "r");
struct YelpDataBST* yelp = malloc(sizeof(struct YelpDataBST*));
int ID = -1;
int tempID;
long int addressOffset;
long int reviewOffset;
char line[2000];
char line2[2000];
char temp[2000];
char temp2[2000];
char* token;
char* token2;
char* name;
int len;
BusList* busNode = NULL;
BusList* busList = NULL;
BusTree* busTreeNode = NULL;
BusTree* busTree = NULL;
ID = -1;
tempID = 0;
fgets(line,2000,fp_rp);
fgets(line2,2000,fp_bp);
fseek(fp_rp,0, SEEK_SET);
fseek(fp_bp,0,SEEK_SET);
int ct = 0;
while(!feof(fp_rp)){
len = strlen(line);
token = strtok(line, "\t");
//printf("line: %s\n", line);
token2 = strtok(line2, "\t");
tempID = atoi((char*)strdup(token));
if(ct == 0){
tempID = 1;
ct++;
}
if((ID != tempID || (ID < 0)) && tempID != 0){
if(tempID == 1)
tempID = 0;
token2 = strtok(NULL, "\t");
//name = strdup(token2);
reviewOffset = ftell(fp_rp);
if(tempID != 0)
reviewOffset -= len;
addressOffset = ftell(fp_bp);
ID = atoi((char*)strdup(token));
busList = BusNode_insert(busList, addressOffset, reviewOffset); //replace with create node for tree
token2 = strtok(NULL, "\t");
token2 = strtok(NULL, "\t");
token2 = strtok(NULL, "\t");
token2 = strtok(NULL, "\t");
token2 = strtok(NULL, "\t");
token2 = strtok(NULL, "\n");
fgets(line2,2000,fp_bp);
}
token = strtok(NULL, "\t");
token = strtok(NULL, "\t");
token = strtok(NULL, "\t");
token = strtok(NULL, "\t");
token = strtok(NULL, "\n");
fgets(line,2000,fp_rp);
}
//BusList_print(busList);
}
strdup(token) segfaulting is most likely explained by token being NULL. (You don't need to strdup here anyway). Change that piece of code to:
if ( token == NULL )
{
fprintf(stderr, "Invalid data in file.\n");
exit(EXIT_FAILURE); // or some other error handling
}
tempID = atoi(token);
However a greater problem with the surrounding code is that you are trying to use strtok twice at once. It maintains internal state and you can only have one strtok "in progress" at any one time. The second one cancels the first one. You'll have to redesign that section of code.
Also, while(!feof(fp_rp)) is wrong, and your yelp mallocs the wrong number of bytes (although in the code posted you never actually try to store anything in that storage, so it would not cause an error just yet).
I'm attempting to read data from a textfile using fgets(), tokenize it using the "|" delimiter and store the results in an array called "menuresult[]". So far, it's failing. It gives me a segfault, and valgrind seems to think it's because of the "strdup" line. I've run out of ideas. Any help would be appreciated. Here's my code so far:
FILE *menufile = fopen("menu.dat", "r");
char *menuresult[1024];
while((fgets(line, sizeof(line), menufile)) != NULL) {
if (i == 0) {
token = strtok(line, "|");
menuresult[i] = strdup(token);
}
else {
token = strtok(NULL, "|");
menuresult[i] = strdup(token);
}
i++;
}
I think you may need these changes-
FILE *menufile = fopen("menu.dat", "r");
char *menuresult[1024];
while((fgets(line, sizeof(line), menufile)) != NULL) {
while((token = strtok(line, "|")) != NULL){
menuresult[i] = strdup(token);
i++;
}
}
Think about this: when you reached the end of line, you are passing a NULL to strdup, it causes undefined behavior. You need a loop to parse every line of the file like this:
while((fgets(line, sizeof(line), menufile)) != NULL) {
token = strtok(line, "|");
menuresult[i] = strdup(token);
printf("%s\n", menuresult[i]);
i++;
while(token){
token = strtok(NULL, "|");
if(token)
{
menuresult[i] = strdup(token);
printf("%s\n", menuresult[i]);
}
i++;
}
}
Your not checking the return of strtok which can return null, plus your replacing line in the while loop, strtok internally keeps track of the string which is why you pass in a null, you prob need a double while loop?
while read file
while strtok != null