Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I am writing a C program to generate userid's from a given file (users). The file has each user's first and last names each line (eg. "John Smith", "Steve Mathews" etc). The following while loop reads each line from users and prints in the console in all lowercase. In this case, single_line holds names in lower case.
while(!feof(fp)) {
fgets(single_line, 80, fp);
for(int i = 0; single_line[i]; i++){
single_line[i] = tolower(single_line[i]);
}
char f_letter = single_line[0];
char r_letters[20];
}
Now, I want to create a username for each single_line with the first letter of the first name and remaining letters of last name. So far, f_letter holds the first letter of first name, how can I make r_letters hold the remaining letters of last name?
char first_name[81];
char last_name[81];
char user_name[82];
while(!feof(fp)) {
if(fscanf(fp, "%80s %80s", first_name,last_name) == 2){
for(i = 0; i < strlen(first_name); i++){
first_name[i] = tolower(first_name[i]);
}
for(i = 0; i < strlen(last_name); i++){
last_name[i] = tolower(last_name[i]);
}
sprintf(user_name, "%c%s", first_name[0], last_name);
}
}
You can use strtok to extract tokens from strings using a delimiter.
For example, for a line of text read from a file using fgets (assuming each line only contains two words, as is your case), you can extract the first and second words as:
char *first_name = strtok(single_line, " ");
char *last_name = strtok(NULL, "\n");
newline character is used as the second delimiter because fgets preserves it when reading a line, so it can be used to extract the last token before the newline.
Consider the following function for creating usernames:
#include <stdio.h>
#include <string.h>
void create_usernames(char *filename) {
char line[80], username[80];
char *last;
FILE *fp = fopen(filename, "r");
// fgets returns a NULL pointer upon EOF or error
while (fgets(line, 80, fp) != NULL) {
last = strtok(line, " ");
last = strtok(NULL, "\n");
printf("%c%s\n", line[0], last);
}
fclose(fp);
}
For example, with a file file.txt containing names:
John Smith
John Diggle
Bruce Wayne
Steve Mathews
you would have:
create_usernames("file.txt");
JSmith
JDiggle
BWayne
SMathews
find the index of the space between the first and last name, say j. the index of the first letter of the last name would be j+1.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I would like to write a program that will open a csv file and create its visualization in a txt file.
I mean:
input:
(this is csv file)
apple;orange;strawberry
car;warsaw;ansi
output in txt file
apple|orange|strawberry
car |warsaw| ansi
The idea is that the width of the whole column should be adjusted to the longest expression in it
output in my program
apple|orange|strawberry
|car|warsaw|ansi
|
I have too many separators, and they're not in line
My code:
#include <stdio.h>
#include <string.h>
#include <string.h>
#define MAXLINE 1000
int how_many_delimiter(char array[]);
int main(void)
{
FILE *f,*f_2;
int *size_of_column, counter, hmd, min;
char corrector[] = ";", rows[MAXLINE], *clipboard;
f = fopen("ex-5.csv", "r");
f_2 = fopen("wynik.txt", "w");
fgets(rows, MAXLINE, f);
hmd = how_many_delimiter(rows);
size_of_column = (int*)calloc(hmd,sizeof(int));
min=10;
while(fgets(rows, MAXLINE, f))
{
clipboard = strtok(rows, corrector);
counter=0;
if(strlen(clipboard)>size_of_column[counter])
{
size_of_column[counter] = strlen(clipboard);
}
while(clipboard!=NULL)
{
if(strlen(clipboard)>size_of_column[counter])
{
size_of_column[counter] = strlen(clipboard);
}
clipboard = strtok(NULL,corrector);
counter++;
}
}
fclose(f);
f = fopen("ex-5.csv", "r");
while(fgets(rows, MAXLINE, f))
{
clipboard = strtok(rows, corrector);
counter=0;
while(clipboard!=NULL)
{
fprintf(f_2,"%-*s|",size_of_column[counter], clipboard);
clipboard = strtok(NULL,corrector);
counter++;
}
}
fclose(f);
fclose(f_2);
return 0;
}
int how_many_delimiter(char array[])
{
int counter, i;
i = 0;
counter = 1;
while(array[i]!='\n'&& array[i]!=EOF)
{
if(array[i]==';') counter++;
i++;
}
return counter;
}
Steps to do this (using an alternate to the "%*s", width method):
Loop to get length of longest word in all categories
int len = strlen(longestWord);
Create format string container char formatStr[80];
Populate formatStr: sprintf(formatStr, "%s%d%s", "%", len+5, "s");
+5 is arbitrary, change as needed for space between columns.
Use formatStr in the printf() statements for each word.
So for example the longest word shown in your example is strawberry. My suggestion was to programmatically parse all of the words into buffers, and loop on them, performing strlen() on each to determine longest. Once you've found, in this case, strawberry, len will be 10, so the format specifier would be "%15s" (if you use my recommended +5). But the value 15 will be in an int variable by then (say for example int longest. Since inserting it directly into the normal format string: ( "%longests" ) will not compile, it will need to be packaged up into a format string, formatStr as shown in bullets above, and here:
sprintf(formatStr, "%s%d%s", "%", longest + 5, "s|");
( Will look like: "%s15s|" )
Once this is done, you can use the format string in the printf statements
This then:
fprintf(f_2,"%-*s|",size_of_column[counter], clipboard);
Becomes:
fprintf(f_2,formatStr, clipboard);
(either method will work.)
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have a struct like this:
struct vertices{
char x[20];
char y[20];
char z[20];
};
and then in main I have an array of the struct vertices like this:
struct vertices vert[64];
plus an array of char in my main function like this:
char exampleArray[200]="v 23.232000 32.33000 2.03900\nv 9.20900 3.29000 1.0002\n";
so what I want to do is to parse this big array containing a hundred or so vertices, and store each value in the corresponding x,y,z char arrays of the struct vertices, which later I'm gonna simply convert by calling on
float x=atof(vert[1].x) and draw each one.
But the problem is that I can't store , copy, concat characters from the raw array to the x,y,z arrays by any ways, i tried to do it by vert[0].x=exampleArray[0], vert[0].x=exampleArray+i etc inside different conditions like
if(SpaceCount==1)
{
vert[0].x[0]=exampleArray[i];
i++;
}
but all this doesn't work.
I tried so many variations, couldn't list them all.
But the thing I want is to parse the exampleArray which has my vertices in raw format, every 3D vertix has spaces in between them, every vertix starts with a char V followed by a space, the first point is the X then followed by a space and then the Y point and after the Z point there is newline \n character and then again a V for a new vertix.
You could use strtok() with delimiter " \n" to get each piece and then strcpy() to place each token in your struct.
struct vertices {
char x[20];
char y[20];
char z[20];
};
int main(void)
{
char exampleArray[200] = "v 23.232000 32.33000 2.03900\nv 9.20900 3.29000 1.0002";
char *toStrtokVertex, *token;
char delim[5] = " \n";
struct vertices V[10];
int i = 0;
toStrtokVertex = exampleArray;
while ((token = strtok(toStrtokVertex, delim)) != NULL) {
// ignore the `v`
// get x
if ((token = strtok(NULL, delim)) != NULL) {
strcpy(V[i].x, token);
}
else {
printf("INPUT ERROR\n");
exit(1);
}
// get y
if ((token = strtok(NULL, delim)) != NULL) {
strcpy(V[i].y, token);
}
else {
printf("INPUT ERROR\n");
exit(1);
}
// get z
if ((token = strtok(NULL, delim)) != NULL) {
strcpy(V[i].z, token);
}
else {
printf("INPUT ERROR\n");
exit(1);
}
// switch this to NULL to keep parsing the same string
toStrtokVertex = NULL;
i++;
}
for (int j = 0; j < i; j++) {
printf("V[%d] (%s, %s, %s)\n", j, V[j].x, V[j].y, V[j].z);
}
}
Note that I modified your input value to match your description. You had
"v 23.232000 32.33000 2.03900\n 9.20900 3.29000 1.0002"
which did not have a v after the \n to start the next vertex, so I added a v
"v 23.232000 32.33000 2.03900\nv 9.20900 3.29000 1.0002"
Character arrays are not copied by simply pointing at them. The function "strcpy(vert[0].x, &exampleArray[2])" is needed, but even then there is no '\0' immediately after that first number to indicate where to stop reading. "memcpy" does not need a NULL ('\0') but needs a length based on spaces.
Further, the "atof" operation to plan to use requires a NULL terminator as well.
I am concerned with your "space planning". You have 64 copies of structures that will each require 60 characters (3840 total), but your exampleArray only has 200. And the input string exampleArray has strings for numbers that must be no longer than 19 digits/decimals because you need the NULL terminator in each of x/y/z to exist.
This is the pure technical evaluation of code issues, but your original post does not show more of the application design. Help us understand your application design and more advice can be given.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I have a text file as follows:
id name area dist
1 surya kumar 1 2
when I try to parse this line in C using strtok() function with space as delimiter I'm getting the output as follows:
1
surya
Kumar
1
2
The second filed is actually a name so it can have multiple spaces in it. Is there a way to treat the second filed as a whole word and still be able to parse the entire line?
As your name may include numbers, I suggest counting the tokens.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXFIELDS 10
int main(void) {
//char input[] = "1 Ludwig 2 3";
char input[] = "1 Ludwig 99 Beethoven 2 3";
char *token[MAXFIELDS];
char *tok;
char name [100];
int fields, index;
int id, area, dist;
fields = 0;
tok = strtok(input, " ");
while(tok != NULL) {
if (fields >= MAXFIELDS)
return 1; // error
token[fields++] = tok;
tok = strtok(NULL, " ");
}
if (fields < 4)
return 1; // error
index = 0;
id = atoi(token[index++]); // id field
strcpy(name, token[index++]); // name field
while(index < fields - 2) {
strcat(name, " "); // append to name
strcat(name, token[index++]);
}
area = atoi(token[index++]); // area field
dist = atoi(token[index++]); // dist field
printf("%d, %s, %d, %d\n", id, name, area, dist);
return 0;
}
Program output
1, Ludwig 99 Beethoven, 2, 3
Before calling strtok, count the number of spaces in the string to know where the 3rd fields does start (i.e. where the second field does end).
Hi I have this program that reads a text file line by line and it's supposed to output the longest word in each sentence. Although it works to a degree, it's overwriting the biggest word with an equally big word which is something I am not sure how to fix. What do I need to think about when editing this program? Thanks
//Program Written and Designed by R.Sharpe
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "memwatch.h"
int main(int argc, char** argv)
{
FILE* file;
file = fopen(argv[1], "r");
char* sentence = (char*)malloc(100*sizeof(char));
while(fgets(sentence, 100, file) != NULL)
{
char* word;
int maxLength = 0;
char* maxWord;
maxWord = (char*)calloc(40, sizeof(char));
word = (char*)calloc(40, sizeof(char));
word = strtok(sentence, " ");
while(word != NULL)
{
//printf("%s\n", word);
if(strlen(word) > maxLength)
{
maxLength = strlen(word);
strcpy(maxWord, word);
}
word = strtok(NULL, " ");
}
printf("%s\n", maxWord);
maxLength = 0; //reset for next sentence;
}
return 0;
}
My textfile that the program is accepting contains this
some line with text
another line of words
Jimmy John took the a apple and something reallyreallylongword it was nonsense
and my output is this
text
another
reallyreallylongword
but I would like the output to be
some
another
reallyreallylongword
EDIT: If anyone plans on using this code, remember when you fix the newline character issue don't forget about the null terminator. This is fixed by setting
sentence[strlen(sentence)-1] = 0 which in effect gets rid of newline character and replaces it with null terminating.
You get each line by using
fgets(sentence, 100, file)
The problem is, the new line character is stored inside sentence. For instance, the first line is "some line with text\n", which makes the longest word "text\n".
To fix it, remove the new line character every time you get sentence.
This question already has an answer here:
C file handling query
(1 answer)
Closed 9 years ago.
So I have a program that takes user input and compares it to a line in the file, before going down onto the next line, if the user gets the word right they get 2 points, if it's wrong they get 1 point. As a failsafe I have added a small function within the program that will take out any spaces from the word.
The program works as expected, the spaces are removed and when run all words are scanned and compared effectively.
HOWEVER, once on the last line of the file, the correct spelling of the word will give the wrong output, this might have something to do with the loops but I'm not sure.
In a nutshell: All I need is one of you talented programmers out there to take a look at my code and see what's causing this to happen.
File content (just a list of random words)
Baby
Milk
Car
Face
Library
Disc
Lollipop
Suck
Food
Pig
(libraries are stdio,conio and string)
char text[100], blank[100];
int c = 0, d = 0;
void space(void);
int main()
{
int loop = 0;
char str[512];
char string[512];
int line = 1;
int dis = 1;
int score = 0;
char text[64];
FILE *fd;
fd = fopen("Student Usernames.txt", "r"); // Should be test
if (fd == NULL)
{
printf("Failed to open file\n");
exit(1);
}
do
{
printf("Enter the string: ");
gets(text);
while (text[c] != '\0')
{
if (!(text[c] == ' ' && text[c] == ' '))
{
string[d] = text[c];
d++;
}
c++;
}
string[d] = '\0';
printf("Text after removing blanks\n%s\n", string);
getch();
for(loop = 0;loop<line;++loop)
{
fgets(str, sizeof(str), fd);
}
printf("\nLine %d: %s\n", dis, str);
dis=dis+1;
str[strlen(str)-1] = '\0';
if(strcmp(string,str) == 0 )
{
printf("Match\n");
score=score+2;
}
else
{
printf("Nope\n");
score=score+1;
}
getch();
c=0;
d=0;
}
while(!feof(fd));
printf("Score: %d",score);
getch();
}
For any input on the last line, the output will always be incorrect, I believe this is something to do with the for loop not turning it into the next variable, but seeing as the <= notation makes this program worse, I really just need a simple fix for the program thanks.
P.S. For anyone who is going to comment about my coding for the spaces function, Yes, I could make it better, but it's not a problem right now. So please don't write anything concerning it.
I guess your file is not terminated by a newline. So the last word, Pig, gets truncated by this line of code:
str[strlen(str)-1] = '\0';
(which is unconditional).
Either put a newline at the end of your file, or check the end-of-string before truncating:
if (isspace(str[strlen(str)-1]))
str[strlen(str)-1] = '\0';
(Might also use strtok to remove all whitespace from the string without writing tricky code)
You need to check if the last character is a linefeed in both the user input and the line read from the file, and remove it if and only if it is. (You also need to fix the other bugs, such as the use of gets and feof, and not all the changes can be done in isolation because some of your bugs depend on one another so fixing only one will break it until you fix the others.)