Number of words in n strings read from a file - c

So i am trying to determine number of words from n strings.The problem I have is that the when I read the number of the strings from the file it somehow count as a string I guess.I am trying to get rid of the first line of the output but can't tell how.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int numar_cuvinte(char *propozitie, char *copie, int numar_propozitii, FILE *f)
{
fgets(propozitie,49,f);
strcpy(copie,propozitie);
char *delimitatori = " ";
char *token = strtok(copie,delimitatori);
int numar_cuvinte = 0;
while(token!=NULL)
{
numar_cuvinte++;
token = strtok(NULL,delimitatori);
}
return numar_cuvinte;
}
int main()
{
FILE *f;
char*name_file = "in.txt";
f=fopen(name_file,"r");
if(f == NULL)
printf("Can't oppen %s",name_file);
int nr_strings;;
fscanf(f,"%d",&nr_strings);
char *propozitie = (char*)malloc(50*sizeof(char));
char *copie = (char*)malloc(50*sizeof(char));
for(int i = 0 ; i <= nr_strings ; i++)
printf("String : %s has %d words \n\n",propozitie,numar_cuvinte(propozitie,copie,nr_strings,f));
free(propozitie);
free(copie);
fclose(f);
return 0;
}

Related

Add parsed elements from text file to array

I am trying to write a code that fetches lines from a txt file and adds parsed out variables from those lines to an array. The txt file reading and the parsing works perfectly.
My text file "inventory.txt" looks like this:
Mars;6
Snickers;7
Bounty;2
Twix;4
MilkyWay;6
KitKat;8
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
//INITIALIZE
char line[100];
char *elements[100] = {};
int i_stock[100];
int r2 = 0;
char item[20] = {0};
int stock;
//DEFINE FILE
FILE *the_file = fopen("inventory.txt","r");
//CHECK IF FILE EXISTS
if(the_file == NULL) {
perror("Inventarfehler");
exit(1);
}
//SCAN LINES FOR STOCK
while(fgets(line, sizeof(line), the_file)) {
sscanf(line, "%[a-zA-Z];%d", &item, &stock);
//ADD VAR TO ARRAY
elements[r2] = item;
r2++;
}
printf(elements[2]);
return 0;
}
Whatever index of elements I print, it is always KitKat. My code keeps overwriting the variables.
printf("%s",elements[2]) should print out Bounty.
Could anyone help me solve this?
Thanks in advance!
The problem is that all of your elements are simple references to item whose content will ultimately be the last candy bar name you read.
Here is one way to solve this problem, by copying each parsed string to a newly-allocated string on the heap using strdup():
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_COUNT 100
int main()
{
//INITIALIZE
char line[MAX_COUNT];
char *elements[MAX_COUNT] = {};
int i_stock[MAX_COUNT];
int r2 = 0;
char item[20] = {0};
int stock;
//DEFINE FILE
FILE *the_file = fopen("inventory.txt", "r");
//CHECK IF FILE EXISTS
if (the_file == NULL)
{
perror("Inventarfehler");
exit(1);
}
//SCAN LINES FOR STOCK
while (r2 < MAX_COUNT && fgets(line, sizeof(line), the_file))
{
sscanf(line, "%[a-zA-Z];%d", item, &stock);
//ADD VAR TO ARRAY
elements[r2] = strdup(item);
r2++;
}
printf("%s\n", elements[2]);
// Free allocated memory
for (int ii = 0; ii < r2; ii++)
{
// printf("Free elements[%d]: %s\n", ii, elements[ii]);
free(elements[ii]);
elements[ii] = NULL;
}
return 0;
}

Finding the most frequent character of an input text file

I am trying to read an input txt file from command line and find the most frequent character in that file for a school project. I can open the txt file and print it without an issue with the following code. Also the funcion below freqcount(), works perfectly when I give it a string from the command line. But I can't seem to make them work together. I think I'm messing up something while setting up the dest array down below. Any help would be appreciated.
Also, for non static sized strings, which one is generally better to use, malloc or calloc?
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#define DEST_SIZE 26 // An arbitrary size but longest string to work is 24
char freqcount(char * str){
// Construct character count array from the input
// string.
int len = strlen(str);
int max = 0; // Initialize max count
char result; // Initialize result
int count[255] = {0};
// Traversing through the string and maintaining
// the count of each character
for (int i = 0; i < len; i++) {
count[str[i]]++;
if (max < count[str[i]]) {
max = count[str[i]];
result = str[i];
}
}
return result;
}
//////////////////////////////////////////////////////////////////////
int main(int argc,char ** argv){
int i=0;
char dest[DEST_SIZE] = {0};
if(argc !=2){
perror("Error: ");
return -1;
}
FILE * f = fopen(argv[1], "r");
if (f == NULL) {
return -1;
}
int c;
while ( (c=fgetc(f)) != EOF && i++<DEST_SIZE ) {
printf("%c",c);
dest[i]=c;
char cnt=freqcount(dest);
printf("%c",cnt);
}
return EXIT_SUCCESS;
}
Sorry I forgot to add, originally call was after the loop such as;
(omitted the first part)
while ( (c=fgetc(f)) != EOF && i++<DEST_SIZE ) {
printf("%c",c);
dest[i]=c;
}
/*int l;
for (l=0; l<DEST_SIZE;l++){
if (dest[i] != 0){
printf("%c\n",dest[l]); // burda da arrayi okuyor ama array 255 long oldugu icin cogu bos
}
}*/
char cnt=freqcount(dest);
printf("%s",cnt);
return EXIT_SUCCESS;
}
when it is like this, the code returns the following with the input "An example Of the input.
An example
Of the input.(null)
Move the call of freqcount to after the while loop:
while ( (c=fgetc(f)) != EOF && i++<DEST_SIZE ) {
printf("%c",c);
dest[i]=c;
}
dest[i]='\0'; // terminate
char cnt=freqcount(dest);
printf("%c",cnt);

C Turning lines of an archive into arrays

I have an archive and I want to turn every line into an array: v[i].data.
However, when I run the code it shows zeros for the arrays.
Is there anything I should change?
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
Actual Output
1761
0
Expected Output
1761
02/20/18,11403.7
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
typedef struct{
char data[20];
}vetor;
int main(int argc,char *argv[]){
FILE *csv;
if((csv=fopen(argv[1], "r")) == NULL )
{
printf("not found csv\n");
exit(1);
}
long int a=0;
char linha[256];
char *token = NULL;
if(fgets(linha, sizeof(linha), csv)) //counting lines
{
token = strtok(linha, "\n");
a =(1 + atoi(token));
}
printf("%d\n", a);
rewind(csv);
vetor *v;
v=(vetor*)malloc(a*sizeof(vetor));
char linha2[256];
while (fgets(linha2, sizeof(linha2), csv) != 0)
{
fseek(csv, +1, SEEK_CUR);
for(int i=0;i<a;i++)
{
fscanf(csv, "%[^\n]", v[i].data);
}
}
printf("%s\n", v[0].data);
fclose(csv);
return 0;
}
There were a number of mistakes so I went ahead and rewrote the problem areas with comments explaining what I did
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char data[20];
}vetor;
int main(int argc,char *argv[]){
FILE *csv;
if((csv=fopen(argv[1], "r")) == NULL )
{
printf("not found csv\n");
exit(1);
}
char line[20];
// Read number of lines
int num_lines = 0;
if (!fgets(line, sizeof(line), csv)) {
printf("Cannot read line\n");
exit(1);
}
char* token = strtok(line, "\n");
num_lines = atoi(token) + 1;
vetor* v = malloc(num_lines * sizeof(vetor));
// Fill in vetor
int i = 0;
while (fgets(line, sizeof(line), csv) != NULL) {
int len = strlen(line);
line[len-1] = '\0'; // replace newline with string terminator
strcpy(v[i].data, line); //copy line into v[i].data
i++;
}
printf("%d\n", num_lines);
for (i = 0; i < num_lines; i++) {
printf("%s\n", v[i].data);
}
return 0;
}
I think the main mistake was a misunderstanding of how best to read in each line of information. If I understood correctly you want each 02/20/18,11403.7 line to be an element in the vetor array.
The easiest way is to simply get each line one at a time with fgets
while (fgets(line, sizeof(line), csv) != NULL)
Change the ending character from newline to the string terminating character '\0'
int len = strlen(line);
line[len-1] = '\0';
Then copy the string into the ith element of vetor and update i for the next iteration of the loop.
strcpy(v[i].data, line);
i++;

Converting Greek words to uppercase

I have to create a function that reads a file called grwords.txt containing around 540000 words which are written in Greek letters.
I have to convert these words to uppercase and fill an array called char **words.
This is what I have so far.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include <ctype.h>
void fp();
int main(int argc, char *argv[]) {
SetConsoleOutputCP(1253);
fp();
return 0;
}
void fp(){
char **words;
words = malloc(546490 * sizeof(int *));
for (i = 0; i < 546490; i++)
words[i] = malloc(24 * sizeof(int));
FILE *file;
char *word;
size_t cnt;
file = fopen("grwords.txt", "rt");
if (file == NULL){
printf("File cannot be opened.\n");
exit(1);
}
cnt = 0;
while (1==fscanf(file, "%24s",word)){
if (cnt == 546490)
break;
strcpy(words[cnt++], word);
}
fclose(file);
}
I'm still trying to figure out pointers. I know that & makes a pointer from a value and * a value from a pointer. Updated the program and it successfully fills the array with the words from the file! I still have no idea how to convert Greek lowercase to uppercase.
Handling Greek words can be dependent on your platform.
First of all, you need to understand how file handling works. Here is what I wrote:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define bufSize 1024 // max lenght of word
// we are going to receive the .txt from cmd line
int main(int argc, char *argv[])
{
FILE *fp;
// Assume file has max 10 words
const size_t N = 10;
// Allocate a 2D array of N rows
// and bufSize columns.
// You can think of it like an array
// of N strings, where every string
// has, at most, bufSize length.
char buf[N][bufSize];
// make sure we got the .txt
if (argc != 2)
{
fprintf(stderr,
"Usage: %s <soure-file>\n", argv[0]);
return 1;
}
// open the file
if ((fp = fopen(argv[1], "r")) == NULL)
{ /* Open source file. */
perror("fopen source-file");
return 1;
}
// we will use that for toupper()
char c;
// counters
int i = 0, j;
while (fscanf(fp, "%1024s", buf[i]) == 1)
{ /* While we don't reach the end of source. */
/* Read characters from source file to fill buffer. */
// print what we read
printf("%s\n", buf[i]);
j = 0;
// while we are on a letter of word placed
// in buf[i]
while (buf[i][j])
{
// make the letter capital and print it
c = buf[i][j];
putchar (toupper(c));
j++;
}
i++;
printf("\ndone with this word\n");
}
// close the file
fclose(fp);
return 0;
}
For this test.txt file:
Georgios
Samaras
Γιώργος
Σαμαράς
the code would run as:
./exe test.txt
Georgios
GEORGIOS
done with this word
Samaras
SAMARAS
done with this word
Γιώργος
Γιώργος
done with this word
Σαμαράς
Σαμαράς
done with this word
As you can see, I could read the Greek words, but failed to convert them in upper case ones.
Once you got how file handling goes, you need to use wide characters to read a file with Greek words.
So, by just modifying the above code, we get:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <wchar.h>
#include <wctype.h>
#include <locale.h>
#define bufSize 1024
int main(int argc, char *argv[])
{
setlocale(LC_CTYPE, "en_GB.UTF-8");
FILE *fp;
const size_t N = 15;
wchar_t buf[N][bufSize];
if (argc != 2)
{
fprintf(stderr,
"Usage: %s <soure-file>\n", argv[0]);
return 1;
}
if ((fp = fopen(argv[1], "r")) == NULL)
{
perror("fopen source-file");
return 1;
}
wchar_t c;
int i = 0, j;
while (fwscanf(fp, L"%ls", buf[i]) == 1)
{
wprintf( L"%ls\n\n", buf[i]);
j = 0;
while (buf[i][j])
{
c = buf[i][j];
putwchar (towupper(c));
j++;
}
i++;
wprintf(L"\ndone with this word\n");
}
fclose(fp);
return 0;
}
And now the output is this:
Georgios
GEORGIOS
done with this word
Samaras
SAMARAS
done with this word
Γιώργος
ΓΙΏΡΓΟΣ
done with this word
Σαμαράς
ΣΑΜΑΡΆΣ
done with this word
I see that you may want to create a function which reads the words. If you need a simple example of functions in C, you can visit my pseudo-site here.
As for the 2D array I mentioned above, this picture might help:
where N is the number of rows (equal to 4) and M is the number of columns (equal to 5). In the code above, N is N and M is bufSize. I explain more here, were you can also found code for dynamic allocation of a 2D array.
I know see that you are on Windows. I tested the code in Ubuntu.
For Windows you might want to take a good look at this question.
So, after you read all the above and understand them, you can see what you asked for with dynamic memory management.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <wchar.h>
#include <wctype.h>
#include <locale.h>
#define bufSize 1024
wchar_t **get(int N, int M);
void free2Darray(wchar_t** p, int N);
int main(int argc, char *argv[])
{
setlocale(LC_CTYPE, "en_GB.UTF-8");
FILE *fp;
const size_t N = 15;
wchar_t** buf = get(N, bufSize);
if (argc != 2)
{
fprintf(stderr,
"Usage: %s <soure-file>\n", argv[0]);
return 1;
}
if ((fp = fopen(argv[1], "r")) == NULL)
{
perror("fopen source-file");
return 1;
}
wchar_t c;
int i = 0, j;
while (fwscanf(fp, L"%ls", buf[i]) == 1)
{
wprintf( L"%ls\n", buf[i]);
j = 0;
while (buf[i][j])
{
c = buf[i][j];
putwchar (towupper(c));
j++;
}
i++;
wprintf(L"\ndone with this word\n");
}
fclose(fp);
// NEVER FORGET, FREE THE DYNAMIC MEMORY
free2Darray(buf, N);
return 0;
}
// We return the pointer
wchar_t **get(int N, int M) /* Allocate the array */
{
/* Check if allocation succeeded. (check for NULL pointer) */
int i;
wchar_t **table;
table = malloc(N*sizeof(wchar_t *));
for(i = 0 ; i < N ; i++)
table[i] = malloc( M*sizeof(wchar_t) );
return table;
}
void free2Darray(wchar_t** p, int N)
{
int i;
for(i = 0 ; i < N ; i++)
free(p[i]);
free(p);
}
Note that this code is expected to work on Linux (tested on Ubuntu 12.04), not on Windows (tested on Win 7).

How to separate and store elements from a string in c?

I have to open a .txt file. Suppose that the content of the file is:
08123, (12/10/2010,M), (01/09/1990,D)
I want to store in different parameters of the string 08123, "12/10/2010" and 'M', for example:
int code = 08123;
char date[10] = '12/10/2010';
char day = 'M';
Also, the last argument finishes with ). How can I iterate it until the line ends?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct date {
char date[11];//+1 for '\0'.
char day;
} Date;
typedef struct rec {
int code;
int dc;//number of Date
Date *dates;
} Record;
Record *parse_rec(char *line){
static const char *sep = ", ";
static const int seplen = 2;//strlen(sep);
Record *rec = malloc(sizeof(*rec));
if(rec){
int i, count = 0;
char *p;
for(p=strstr(line, sep);p;p = strstr(p+seplen, sep)){
++count;
}
rec->dc = count;
rec->dates = malloc(count*sizeof(Date));
rec->code = atoi(line);
line = strstr(line, sep) + seplen;
for(i=0;i<count;++i){
sscanf(line, "(%[^,],%c", rec->dates[i].date, &rec->dates[i].day);
line = strstr(line, sep) + seplen;
}
}
return rec;
}
int main(void){
char line[1024];
FILE *fp = fopen("data.txt", "r");
fgets(line, sizeof(line), fp);
fclose(fp);
Record *rec = parse_rec(line);
printf("code: %05d\n", rec->code);
for(int i=0;i < rec->dc; ++i){
printf("date : %s\n", rec->dates[i].date);
printf(" day : %c\n", rec->dates[i].day);
}
free(rec->dates);
free(rec);
return 0;
}

Resources