Storing Token Char Array in C - c

I'm having some issues trying to print out an array of characters (storage) that hold tokens (tok). Everytime I print the array I get a strange symbol.
while(1)
{
printf("repl>");
char storage [30];
char* tok;
char g;
char buffer[20];
int pos = 0, i;
size_t bufferlength = 20;
fgets(buffer,sizeof(buffer),stdin);
tok = strtok(buffer," ");
while (tok != NULL)
{
storage[pos] = tok;
tok = strtok(NULL," ");
pos++;
}
printf(" %c\n", storage[0]);
}

Related

How i can create a function for reading structure from a test.txt

How i can create a function for reading structure from a test.txt. I have a good works code in main, but i need to carry out it from main(). How combine (struct student PI1[N] and (fread() or fgets() or fwrite()));
struct student {
char surname[50];
char name[50];
char dayBirth[50];
int mark;
};
struct student PI1[N];
int main()
{
int counter = 0;
char str[50];
const char s[2] = " ";
char* token;
FILE* ptr;
int i = 0;
ptr = fopen("test.txt", "r");
if (NULL == ptr) {
printf("file can't be opened \n");
}
char* tmp;
int Itmp;
while (fgets(str, 50, ptr) != NULL) {
token = strtok(str, s);
strcpy(PI1[i].surname, token);
token = strtok(NULL, s);
strcpy(PI1[i].name, token);
token = strtok(NULL, s);
strcpy(PI1[i].dayBirth, token);
token = strtok(NULL, s);
Itmp = atoi(token);
PI1[i].mark = Itmp;
i++;
counter++;
}
}
Rather than "can create a function for reading structure from a test.txt", start with a function to convert a string from fgets() into a struct. Then call it as needed.
Use sprintf() and " %n" to detect complete scan with no extra text.
// Return success flag
bool string_to_student(struct student *stu, const char *s) {
int n = 0;
sscanf(s, "%49s%49s%49s%d %n", stu->surname, stu->name,
stu->dayBirth, &stu->mark, &n);
return n > 0 && s[n] == '\0';
}
Use
while (i < N && fgets(str, sizeof str, ptr) &&
string_to_student(&PI1[i], str)) {
i++;
}
counter = i;

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

How to fill fields in a Struct type? error: variable-sized object may not be initialized

Having trouble using malloc to create each row vector to store data in. Also, I can't seem to assign the fields of struct using functions I've coded.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "redo_hw4_functs.h"
typedef struct _Stores{
char name[10];
char addr[50];
char city[30];
char state[3];
} Store;
//function that creates a new matrix of size r x c
int main(int argc, char* argv[])
{
Store* pStores;
FILE* pFile;
char* stateGiven;
char buffer[180];
char* storeGiven;
char lineChar;
int lineNumb = 0;
int r;
char* tempName, tempAddr, tempCity, tempState;
if(argc < 4){
printf("Too few arguments! \n");
}
else if(argc > 4){
printf("Too many arguments! \n");
}
pFile = fopen(argv[1],"r");
for (lineChar = getc(pFile); lineChar != EOF; lineChar = getc(pFile))
{
if (lineChar == '\n') // Increment count if this character is newline
lineNumb = lineNumb + 1;
}
fclose(pFile);
pFile = fopen(argv[1],"r");
while(fgets(buffer, sizeof(buffer), pFile) != NULL)
{
for (r = 0; r < lineNumb; r++)
{
pStores = realloc(pStores, lineNumb * sizeof(Store*));
Store pStores[r] = malloc(sizeof(Store));
getName(pStores[r].name, buffer);
getAddress(pStores[r].addr, buffer);
getCity(pStores[r].city, buffer);
getState(pStores[r].state, buffer);
printf(" Store name: %s \n", pStores[r].name);
printf(" Address: %s \n", pStores[r].addr);
printf(" City: %s \n", pStores[r].city);
printf(" State: %s \n", pStores[r].state);
}
}
}
^^^ In the above block of code I made some improvements and also included realloc(). I initialized the lineNumb variable. I believe the problem regarding my initialization of each row that Store* pStores is trying to reference/point to.
Here are the helper functions:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "redo_hw4_functs.h"
//accepts a line of string formatted as expected and stores the store name in char file
void getName(char strName[], char strLine[])
{
char* token;
char delim[] = " ,\t\n";
token = strtok(strLine, delim);
while(token != NULL)
{
if(strcmp(token, "sears") == 0 || strcmp(token, "kmart"))
{
strcpy(strName, token);
break;
}
token = strtok(NULL, delim);
}
}
//accepts a line of string formatted as expected and stores the store address in char file
void getAddress(char strAddress[], char strLine[])
{
char* token;
char delim[] = ",\t\n";
token = strtok(strLine, delim);
while(token != NULL)
{
if(isdigit(token[0]) && isalpha(token[sizeof(token)-1]))
{
strcpy(strAddress, token);
break;
}
token = strtok(NULL, delim);
}
}
//accepts a line of string formatted as expected and stores the store city in char file
void getCity(char strCity[], char strLine[])
{
int i;
char* token;
char delim[] = ",\t\n";
token = strtok(strLine, delim);
while( token != NULL )
{
strcpy(strCity, token + strlen(token)-3);
token = strtok(NULL, delim);
}
}
//accepts a line of string formatted as expected and stores the store state in char file ¡OJO! This is the hardest one because you cant rely on delimeters alone to find state
void getState(char strState[], char strLine[])
{
int i;
char* token;
char delim[] = "\n";
token = strtok(strLine, delim);
while( token != NULL )
{
strcpy(strState, token + strlen(token)-3);
token = strtok(NULL, delim);
}
}
Here is some sample input:
Kmart, 217 Forks Of River Pkwy, Sevierville TN
Kmart, 4110 E Sprague Ave, Spokane WA
Kmart, 1450 Summit Avenue, Oconomowoc WI
Sears, 2050 Southgate Rd, Colorado Spgs CO
Sears, 1650 Briargate Blvd, Colorado Spgs CO
Sears, 3201 Dillon Dr, Pueblo CO

Unable to achieve expected parsing output with strtok

I have been working on this for a while now but I do not seem to be able to resolve this bug. Any insights will be greatly appreciated thanks.
I am writing code that will parse a string first by ";" and then by " ". The code I have below is as follows:
void arrayVis(char **arr, int size){
printf("[");
for(int i = 0; i < size; i++){
if(arr[i] == NULL || strcmp(arr[i], "") == 0){
break;
}
printf("%s,", arr[i]);
}
void parser2(char *line){
char *token = strtok(line, " ");
char *arr[10];
int index = 0;
while(token != NULL){
arr[index] = token;
token = strtok(NULL, " ");
index++;
}
arrayVis(arr, 10);
}
void parser1(char *line){
char *token = strtok(line, ";");
while(token != NULL){
parser2(token);
// myPrint(token);
printf("\n");
token = strtok(NULL, ";");
}
}
array vis will just allow me to visualize the array that is produced. When I pass "1 2 3;4 5 6;"
I am expecting an output of
[1,2,3
[4,5,6
but instead I just get the output
[1,2,3
Why is my output omitting the second portion of the parse? I have been thinking about this for a while now but I dont seem to understand why this happens. Any insights will be appreciated. Thank you.
int main(void) {
static const char *ROW_TOKENS=";";
static const char *COL_TOKENS=" ";
char buf[] = "data1;data2 data3;data4 data5";
char *aux_row,*cursor_row;
cursor_row = strtok_r(buf, ROW_TOKENS, &aux_row);
// printf("[A] buf: %p, cursor_row=%p, aux_row=%p\n", buf, cursor_row, aux_row);
while (cursor_row) {
char *aux_col,*cursor_col;
printf("[");
cursor_col = strtok_r(cursor_row, COL_TOKENS, &aux_col);
// printf("[B] cursor_row=%p, aux_row=%p, cursor_col=%p, aux_col=%p\n",
// cursor_row, aux_row, cursor_col, aux_col);
while (cursor_col) {
// printf("[C] cursor_row=%p, aux_row=%p, cursor_col=%p, aux_col=%p\n",
// cursor_row, aux_row, cursor_col, aux_col);
printf("%s,", cursor_col);
cursor_col = strtok_r(NULL, COL_TOKENS, &aux_col);
}
cursor_row = strtok_r(NULL, ROW_TOKENS, &aux_row);
printf("\n");
}
return 0;
}

Breaking down a string and putting it into array using strtok()

I'm writing a basic program that takes a CSV file, prints the first field, and does some numerical evaluation of the other fields.
I'm looking to put all the numerical fields into an array but every time I do this and try to access a random element of the array, it prints the entire thing
My CSV file is:
Exp1,10,12,13
Exp2,15,16,19
and i'm trying to access the second field so it prints
Exp1 12
Exp2 16
but instead I'm getting
Exp1 101213
Exp2 151619
If someone could provide some suggestions. This is my code:
#define DELIM ","
int main(int argc, char *argv[])
{
if(argc == 2) {
FILE *txt_file;
txt_file = fopen(argv[1], "rt");
if(!txt_file) {
printf("File does not exist.\n");
return 1;
}
char tmp[4096];
char data[4096];
char expName[100];
char *tok;
int i;
while(1){
if(!fgets(tmp, sizeof(tmp), txt_file)) break;
//prints the experiment name
tok = strtok(tmp, DELIM);
strncpy(expName, tok, sizeof(expName));
printf("\n%s ", expName);
while(tok != NULL) {
tok = strtok(NULL, DELIM);
//puts data fields into an array
for(i=0; i < sizeof(data); i++) {
if(tok != NULL) {
data[i] = atoi(tok);
}
}
printf("%d", data[1]);
}
}
fclose(txt_file);
return 0;
}
sample to fix
char tmp[4096];
int data[2048];
char expName[100];
char *tok;
int i=0;
while(fgets(tmp, sizeof(tmp), txt_file)){
tok = strtok(tmp, DELIM);
strncpy(expName, tok, sizeof(expName));
printf("\n%s ", expName);
while((tok = strtok(NULL, DELIM))!=NULL){
data[i++] = atoi(tok);
}
printf("%d", data[1]);
i = 0;
}
A modified code snippet:
int data[20]; // change 20 to a reasonable value
...
while (1)
{ if (!fgets(tmp, sizeof(tmp), txt_file))
break;
//prints the experiment name
tok = strtok(tmp, DELIM);
strncpy(expName, tok, sizeof(expName));
printf("\n%s ", expName);
i = 0;
tok = strtok(NULL, DELIM);
while (tok != NULL)
{ //puts data fields into an array
data[i++] = atoi(tok);
if (i == 20)
break;
tok = strtok(NULL, DELIM);
}
if (i > 1)
printf("%d", data[1]);
}

Resources