Using strtok while rewriting CSV archives for Excel - c

I'm trying to write an Excel archive(input) into an empty archive. The aim is to write a new Excel without the dates, but when I try, the new archive is erasing some lines in the excel and not erasing the dates as I wanted to. Is it something with the code?
Input
1760
02/20/18,11403.7
02/19/18,11225.3
02/18/18,10551.8
02/17/18,11112.7
02/16/18,10233.9
02/15/18,10166.4
02/14/18,9494.63
02/13/18,8598.31
Actual Output
1760
02/20/18
11403.7
02/19/18
11225.3
02/18/18
10551.8
02/17/18
11112.7
02/16/18
10233.9
02/15/18
10166.4
02/14/18
9494.63
02/13/18
8598.31
Expected Output
1760
11403.7
11225.3
10551.8
11112.7
10233.9
10166.4
9494.63
8598.31
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
int main(int argc,char **argv){
FILE *btc;
FILE *out;
if((out = fopen("new.csv", "w")) == NULL ){
printf("not found new\n");
exit(1);
}
if((btc = fopen("BTC.csv", "r")) == NULL ){
printf("not found btc\n");
exit(1);
}
long int a;
char linha[256];
char *token = NULL;
while (!feof(btc))
{
fgets(linha, 256, btc);
token = strtok(linha, ",\n");
while ((token != NULL) && (!feof(btc)))
{
a++;
fprintf(out, "%s\n", token);
token = strtok(NULL, " \n");
}
}
fclose(btc);
fclose(out);
return 0;
}

As far as I can see, you want to drop the date field, which is the first field. You need to arrange not to print the first token found by strtok() on each line — except the first where you should probably print 1760 by not scanning the 1 as a separate operation.
That leads to code like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
const char *name1 = "BTC.csv";
const char *name2 = "new.csv";
FILE *out;
FILE *btc;
if ((btc = fopen(name1, "r")) == NULL)
{
fprintf(stderr, "failed to open file %s for reading\n", name1);
exit(1);
}
if ((out = fopen(name2, "w")) == NULL)
{
fprintf(stderr, "failed to open file %s for writing\n", name2);
exit(1);
}
int lineno = 0;
char linha[256];
char *token = NULL;
while (fgets(linha, sizeof(linha), btc) != 0)
{
if (++lineno == 1)
fprintf(out, "%s", linha);
else
{
token = strtok(linha, ",\n");
if (token == NULL)
break;
while ((token = strtok(NULL, ",\n")) != 0)
fprintf(out, "%s\n", token);
}
}
fclose(btc);
fclose(out);
return 0;
}
Given input file BTC.csv:
1760
02/20/18,11403.7
02/19/18,11225.3
02/18/18,10551.8
02/17/18,11112.7
02/16/18,10233.9
02/15/18,10166.4
02/14/18,9494.63
02/13/18,8598.31
the program creates output file new.csv:
1760
11403.7
11225.3
10551.8
11112.7
10233.9
10166.4
9494.63
8598.31
This seems to correspond to what is wanted.

Related

How do I check if every word in a text file is in a dictionary that contains every English word?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char file(FILE *fh, char c[45]);
int lejiko(FILE *lh);
void split(FILE *fh);
int main() {
int choice;
char c[45];
FILE *fh;
FILE *lh;
file(fh, c);
lejiko(lh);
split(fh);
return 0;
}
char file(FILE *fh, char c[45]){
fh = fopen("test.txt", "r");
if (fh != NULL) {
printf("Loaded File");
/* while ((c = fgetc(fh)) != EOF)
putchar(c); */
} else
printf("ERROR");
fclose(fh);
return c;
}
int lejiko(FILE *lh) {
int count = 0;
char t;
lh = fopen("englishWords.txt", "a+");
if (lh != NULL) {
printf("\nLoaded Dictionary");
}
for (t = getc(lh); t != EOF; t = getc(lh))
if (t == '\n')
count = count + 1;
printf("\nYparxoun %d lejeis sto lejiko.\n", count);
return count;
}
void split(FILE *fh) {
char array[45];
char *spl;
fh = fopen("test.txt", "r");
if (fh == NULL)
perror("Error opening file");
else {
while (fgets(array, 45, fh) != NULL) {
printf("%s\n", array);
spl = strtok(array, " ");
while (spl != NULL) {
printf("%s\n", spl);
spl = strtok(NULL, " ");
}
}
fclose(fh);
}
return 0;
}
FILE:I dont know what this is.im.just.testing.out.
Output:
I
dont
know
what
this
is.im.just.testing.out
.
.
This is what I have accomplished so far. I think that the way this will work is by storing every word from the text file and the dictionary in to two matrices and from there by comparing the elements of the matrices.So far i have managed to separate each word whenever there is a space, but when there is punctuation in the text it doesn't seem to work. I have tried multiple ways to remove punctuation from the text, but I cannot get it to work. Also dont mind the functions that just print their names, they will be used for later versions.

C program to print line number in which given string exists in a text file

I have written a C program that opens a text file and compares the given string with the string present in the file. I'm trying to print the line number in which the same string occurs, but I am unable to get the proper output: output does not print the correct line number.
I would appreciate any help anyone can offer, Thank you!
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
int num = 0, line_number = 1;
char string[50];
char student[100] = { 0 }, chr;
while (student[0] != '0') {
FILE *in_file = fopen("student.txt", "r");
if (in_file == NULL) {
printf("Error file missing\n");
exit(1);
}
printf("please enter a word \n");
scanf("%s", student);
while (fscanf(in_file, "%s", string) == 1) {
if (chr == '\n') {
if (strstr(string, student) == 0) {
break;
} else
line_number += 1;
}
}
printf("line number is: %d\n", line_number);
fclose(in_file);
}
return 0;
}
You cannot read lines with while (fscanf(in_file, "%s", string), the newlines will be consumed by fscanf() preventing you from counting them.
Here is an alternative using fgets():
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char string[200];
char student[100];
int num = 0, line_number = 1;
FILE *in_file = fopen("student.txt", "r");
if (in_file == NULL) {
printf("Error file missing\n");
exit(1);
}
printf("please enter a word \n");
if (scanf("%s", student) != 1) {
printf("No input\n");
exit(1);
}
while (fgets(string, sizeof string, in_file)) {
if (strstr(string, student)) {
printf("line number is: %d\n", line_number);
}
if (strchr(string, '\n')) {
line_number += 1;
}
fclose(in_file);
}
return 0;
}

Split a string that I read from a file

I have a file like this
GET /index.html k
GET /docencia.html k
GET /ejemplo.html k
and I want to read it line by line and split it up with this delimiter " " but is giving me this error: segmentation fault(core dumped) and I don't know what to try.
This is my code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
char ordenes[150];
char *orden[3];
char *token;
int tok;
FILE *fp;
fp = fopen(argv[1], "r");
if (fp == NULL) {
printf("File error");
exit(1);
}
while (feof(fp) == 0) {
fgets(ordenes, sizeof(ordenes), fp);
printf("%s \n", ordenes);
token = strtok(ordenes, " ");
tok = 0;
while (token != NULL) {
orden[tok] = strdup(token);
tok++;
token = strtok(NULL, " ");
}
printf("\n%s\n", orden[0]);
printf("\n%s\n", orden[1]);
printf("\n%s\n", orden[2]);
}
fclose(fp);
}
The error shows when I call the first strdup. If I try to print the token just after I call the first strtok, it fails too (the same segmentation fault core dumped) so I guess the problem is with the strtok.
You do not include <string.h>, so the compiler applies the default argument promotions on the signature of strtok, in particular it considers that strtok returns an int.
So the compiler will apply an operator of coercion from int to pointer to char at the assignment
token = strtok(ordenes, " ");
and this assignment will be compiled as
token = (int->char*) strtok(ordenes, " ");
There are multiple problems in your code:
As alinsoar diagnosed with a sharp eye, you do not include <string.h>. strtok is not defined, the compiler must assume it returns an int, which it does not, and this int is silently converted to a char *. The code generated invokes undefined behavior and will most likely crash on 64-bit targets. You should compile with all warnings enabled to let the compiler help avoid this kind of silly mistake. gcc -Wall -W or clang -Weverything...
You do not check if command line arguments have been passed to your program before calling fp = fopen(argv[1], "r");. If no arguments are passed, argv[1] is a null pointer.
while (feof(fp) == 0) is incorrect, read Why is “while ( !feof (file) )” always wrong? . You should instead write while (fgets(ordenes, sizeof(ordenes), fp)) {...
You do not check if tok < 3 before storing token into the orden array. If the line has more than 3 fields, you will cause a buffer overflow.
You do not check if 3 tokens were indeed found before printing all 3 entries in orden. This too might invoke undefined behavior, especially if fgets() failed to read a line, which you do not check.
Here is an improved version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char ordenes[150];
char *orden[3];
char *token;
int i, tok;
if (argc < 2) {
fprintf(stderr, "Missing command line argument\n");
exit(1);
}
FILE *fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "Cannot open input file %s: %s\n",
argv[1], strerror(errno));
exit(1);
}
while (fgets(ordenes, sizeof(ordenes), fp)) {
printf("%s", ordenes);
token = strtok(ordenes, " ");
for (tok = 0; tok < 3 && token != NULL; tok++) {
orden[tok] = strdup(token);
token = strtok(NULL, " ");
}
for (i = 0; i < tok; i++) {
printf("%s\n", orden[i]);
free(orden[i]);
}
printf("\n");
}
fclose(fp);
return 0;
}
For starters you should change the condition in the outer loop statement the following way
while ( fgets(ordenes, sizeof(ordenes), fp) != NULL )
The condition in the inner loop should be written at least like
while ( tok < 3 && token != NULL) {
The tokens should be outputted in a loop and the allocated memory must be freed. For example
for ( int i = 0; i < tok; i++ )
{
printf("\n%s\n", orden[i]);
free( orden[i]);
}
You can do the following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void play_with_token(char *token, char const *delim)
{
if (token == NULL)
return;
printf(" %s", token);
play_with_token(strtok(NULL, delim), delim);
}
int main(int argc, char *argv[])
{
if (argc != 2)
return 1;
FILE *fp = fopen(argv[1], "r");
if (fp == NULL)
return 1;
char *line = NULL;
size_t len = 0;
ssize_t read;
while ((read = getline(&line, &len, fp)) != -1) {
printf("parsing line :");
char const *delim = " ";
play_with_token(strtok(line, delim), delim);
printf("\n");
}
free(line);
fclose(fp);
}
try this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
char ordenes[150];
char *orden[3];
char *token;
int tok;
FILE *fp;
fp = fopen (argv[1], "r");
if(fp==NULL){
printf("File error");
exit(1);
}
while(fgets(ordenes, sizeof(ordenes), fp)){
printf("%s\n",ordenes);
token = strtok(ordenes, " ");
tok = 0;
while (token != NULL){
orden[tok++] = strdup(token);
token = strtok(NULL," ");
}
printf("\n%s\n",orden[0]);
printf("\n%s\n",orden[1]);
printf("\n%s\n",orden[2]);
free(orden[0]);free(orden[1]);free(orden[2]);
}
fclose(fp);
}

C - fopen() doesn't work (returns null pointer) [duplicate]

This question already has answers here:
Why does 'fopen' return a NULL pointer?
(8 answers)
Closed 8 years ago.
Why does fopen() return a null pointer?
I'm trying to save the parameters after BRIDGE and after LAN (respectively 4 and 5) in cont_br and cont_lan, but fopen() doesn't work...
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
void read_file(char file[]) {
char cont, *str, *ctrl_str;
int x=0, cont_br, cont_lan;
FILE *file_stream;
if (file_stream = fopen(file, "r")) {
while( !feof(file_stream) ) { //Check the file dimension
fgetc( file_stream );
x++;
}
x--;
str = (char*) malloc(sizeof(char) * x+1);
fseek(file_stream, 0, SEEK_SET); // Return at the beginning of the file
fread(str, x, 1, file_stream);
char delims[] = "#";
char *result = NULL;
result = strtok( str, delims);
while (result != NULL) {
if (result == "BRIDGE") { //Check the different "blocks" in the txt file
result = strtok(NULL, delims);
cont_br = atoi(result);
printf("Number of bridges: %d\n", cont_br);
}
result = strtok(NULL, delims);
if (result == "LAN") {
result = strtok(NULL, delims);
cont_lan = atoi(result);
printf("Number of Lan: %d\n", cont_lan);
}
break; //
}
}
printf("Error: can't open the file! errno: %d\n", errno);
fclose(file_stream);
}
int main() {
char file[] = "Config.txt";
read_file(file);
return 0;
}
And this is the Config.txt file:
BRIDGE#4#
LAN#5#
192.168.0.1
192.168.1.1
192.168.2.1
192.168.3.1
192.168.4.1
#
LINK#
B1:3000,L1
B1:3001,L2
B1:3002,L3
B2:3000,L4
B2:3001,L5
B3:3000,L1
B4:3000,L3
B5:3000,L2
B2:3002,L3
Whenever fopen fails then print the error number (errno).
#include <error.h>
You should include the standard errno.h and print the value of error in your code. Then look at the error code and find the reason.
Example
#include <stdio.h>
#include <errno.h>
int main()
{
errno = 0;
FILE *fb = fopen("/home/jeegar/filename", "r");
if (fb==NULL) {
printf("Error %d \n", errno);
printf("It's null");
}
else
printf("working");
}
This way if fopen fails then it will set the error number. You can find those error number lists in fopen.

where is the pthread segfault happening?

in my program, I provide a directory which contains text files. Each of the text files contain a few hundred lines in the following format
Username,Password,BloodType,Domain,Number
I then create a thread for each file in the directory which will merge-sort(by number) these lines into the array char* text_lines[6000];
I can't figure out why I'm getting a segmentation fault because I'm getting different output on every run.
Heres my code:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
void store_line(char* line);
void* my_merge_sort(void* file);
char** text_lines;
int main(int argc, char* argv[])
{
if(argc != 2)
{
fprintf(stderr, "usage: ./coolsort <directory>\n");
}
else
{
text_lines = malloc(6000 * sizeof(char*));
DIR* the_directory;
int filecount = 0;
struct dirent* directory_files[50];
if((the_directory = opendir(argv[1])) != NULL)
{
//make a list of the files in the directory
while((directory_files[filecount++] = readdir(the_directory))) ;
filecount--;
//<<<DEBUGGING INFO>
int i;
fprintf(stderr,"there are %i files in %s:\n", filecount, argv[1]);
for(i = 0; i < filecount; i++)
{
fprintf(stderr, "%s\n",directory_files[i]->d_name);
}
char cwd[512];
chdir(argv[1]);
getcwd(cwd, sizeof(cwd));
fprintf(stderr, "the CWD is: %s\n", cwd);
//<DEBUGGING INFO>>>
//lets start some threads
pthread_t threads[filecount-2];
int x = 0;
for(i = 0; i < (filecount); i++ )
{
if (!strcmp (directory_files[i]->d_name, "."))
continue;
if (!strcmp (directory_files[i]->d_name, ".."))
continue;
pthread_create(&threads[x++], NULL, my_merge_sort, (void*)directory_files[i]->d_name);
}
//do stuff here
//
}
else
{
fprintf(stderr, "Failed to open directory: %s\n", argv[1]);
}
}
}
void* my_merge_sort(void* file)
{
fprintf(stderr, "We got into the function!\n");
FILE* fp = fopen(file, "r");
char* buffer;
char* line;
char delim[2] = "\n";
int numbytes;
//minimize I/O's by reading the entire file into memory;
fseek(fp, 0L, SEEK_END);
numbytes = ftell(fp);
fseek(fp, 0L, SEEK_SET);
buffer = (char*)calloc(numbytes, sizeof(char));
fread(buffer, sizeof(char), numbytes, fp);
fclose(fp);
//now read the buffer by '\n' delimiters
line = strtok(buffer, delim);
fprintf(stderr, "Heres the while loop\n");
while(line != NULL)
{
store_line(line);
line = strtok(buffer, NULL);
}
free(buffer);
}
void store_line(char* line)
{
//extract the ID.no, which is the fifth comma-seperated-token.
char delim[] = ",";
char* buff;
int id;
int i;
strtok(line, delim);
for(i = 0; i < 3; i++)
{
strtok(line, NULL);
}
buff = strtok(line, NULL);
id = atoi(buff);
//copy the line to text_lines[id]
memcpy(text_lines[id], line, strlen(line));
}
edit: I checked to make sure that it would fit into the initial array, and found that the highest ID is only 3000;
You use of strtok() is wrong:
line = strtok(buffer, NULL);
should be
line = strtok(NULL, delim);
Another mistakes should be fixed similarly.
The elements of text_lines are uninitialized:
text_lines = malloc(6000 * sizeof(char*));
this allocated 6000 pointers to char, but none of these pointers are initialized.

Resources