strtok inserting junk into an array [closed] - c

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I'm having some issues with strtok, Im basically reading a file line by line, separating the data I get from the file with strtok and then storing it into an array.
A row in my file looks like this (I have several lines, but the idea is the same).
file.txt
3 0 5 0 0 8 0 1 0
Im doing the following
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void){
FILE* file;
char line[256];
char* data[9];
char* fileName = "file.txt";
file = fopen(fileName, "r");
fgets(line, sizeof(line), file);
char* ptr = strtok(line," ");
int i = 0;
while(ptr != NULL && i<9){
printf("%s",ptr);
data[i] = ptr;
i++;
ptr = strtok(NULL, " ");
}
for(int z = 0; z<i; z++){
printf( "%s", data[z]) ;
};
fclose(file);
}
Which gives me the output
3,0,5,0,0,8,0,1,0, (from the printf inside the while)
p��0�,�0�,�,,0,8,0,1,0 (from the data array)
Any idea on whats going on?
EDIT: Added spacing in txt file and separation between outputs. i<9 was added in while statement (i<8 made it so the last digit was not being catched).
EDIT2: Problem was fixed by using data[9] instead of data[8], being an array I thought the first element would be data[0] being data[8] the ninth.
Current output with code above:
3,0,5,0,0,8,0,1,0, (From ptr)
3,0,5,0,0,8,0,1,0, (From data array)

First of all you are allocating way too small buffer for your line. Use line[255] or even bigger. Next you are trying to print null pointers from data array and z<9 will lead to access out of bounds on index 8 as the last entry in data array is actually at index 7. So the best solution will be to limit for loop by i which actually equals size of read data entries.
for(int z = 0; z<i; z++){
printf( "%s", data[z]);
}
So you will be printing only non null entries from data array.
Last but not least as your data array can fit only 8 entries you need also change while loop to fit this limitation (or increase the size of the array):
while (ptr != NULL && i < 8) {
...
}

Related

C Program stopped working after using scanf instead of var=0 [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 4 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
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.
Improve this question
So I have this code:
#include <stdio.h>
#include <stdlib.h>
int functie ( int v[], int nr, int z)
{
int i,count;
scanf("%d", &z);
for(i=0;i<nr;i++) {
if(z==v[i]) {
count=count+1;
}
}
return z;
}
int main()
{
int i,nr,z;
fscanf("%d", &z);
FILE *f;
FILE *g;
f=fopen("data-in.txt", "r");
fscanf(f,"%d",&nr);
int *v=malloc(nr*sizeof(int));
for(i=0;i<nr;i++) {
fscanf(f,"%d",&v[i]);
}
g=fopen("data-out.txt", "w");
fprintf(g,"%d %d", functie(v,nr,z));
fclose(f);
fclose(g);
free(v);
}
and before I had int z=0; instead of trying to scanf my var z.
When I run this I get a stopped working error.
I have an array with numbers (integers) read from file, first line is the number of elements and second line the elements.
I need a var lets say z to check how many times an element appears in vector (check if scanned number z is equal to an element and +1 count )
example:
in file
4 (cuz I have 4 elements )
1 2 3 3 ( my elements )
than scan z as 3
z==3 true
count=1
again
count=2
Two issues here, both in main. First:
fscanf("%d", &z);
This function expects a FILE * for the first argument, which you didn't specify. Presumably you wanted to read from the console instead, so use scanf:
scanf("%d", &z);
Second issue:
fprintf(g,"%d %d", functie(v,nr,z));
Your format string is expecting two integer arguments, but you're only passing in one. Get rid of the extra format specifier:
fprintf(g,"%d", functie(v,nr,z));
fscanf will not be delimited by newlines. Best thing to do is eat through file a line at a time with fgets. So, add a line buffer to the top of main:
char line[16]; // assuming integers will actually be small
After opening your file as above with 'f':
if (fgets(line, sizeof(line), f))
{
int count = atoi(line);
int *v = (int *) malloc(count * sizeof(int));
for (int i = 0; i < count && fgets(line, sizeof(line), f); ++i)
{
v[i] = atoi(line);
}
}
You should absolutely add error checking to the above, which is minimal and for concept only (e.g. guard against bad input, buffer overflow, exceptions, count being wrong leaving you uninitialized integers at the end of the array, etc.) as this will only work if your input file is perfect. Note that 16 is generally a ridiculously small length for a line buffer. Also only do your logic against your vector if (a) the file opens, and (b) passes the first test, which is an integral number of entries.

Why does my array still contain garbage values even after "clearing" them in C [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I am trying to obtain the first two strings from the first line of stdin using the following code.
#include <stdio.h>
#include <string.h> // for memset
int main(void) {
#define MAX_LINE_LEN 20
char heightWidth[MAX_LINE_LEN]; // allocate 50 chars to heightWidth
memset(heightWidth, 0, MAX_LINE_LEN);
fgets(heightWidth, MAX_LINE_LEN, stdin); // first line stored in heightWidth
char str1[MAX_LINE_LEN];
char str2[MAX_LINE_LEN];
memset(str1, 0, MAX_LINE_LEN);
memset(str1, 0, MAX_LINE_LEN);
int index = 0; // stores the current char index of str array
int strNumber = 1;
char currChar;
for (int i = 0; i < MAX_LINE_LEN; i++) {
if (strNumber > 2) { // if we've read two strings, break
break;
}
currChar = heightWidth[i]; // asssign current char to currChar
if (currChar == ' ') { // if current character is a space, continue
strNumber++; // increment strNumber
index = 0; // reset the index
continue;
}
// otherwise add it to one of our arrays
if (strNumber == 1) {
str1[index] = currChar;
} else {
str2[index] = currChar;
}
index++; // increment index
}
puts(str1);
puts(str2);
return 0;
}
However, when I enter three space separated strings or more, I sometimes get garbage values appended to the second string.
asdf 234 sdf // user input
asdf // first string printed is ok
234�� // second string has garbage appended
I initially though this was because the memory allocated to those arrays still had their previous values in them (hence my use of memset to "clear" them) but adding memset didn't seem to fix my issue.
What is the problem here and how can I edit my code to obtain two strings that are space separated?
You have a typo and instead of zeroing the second string you're zeroing the first one twice.
Ditch the memset calls (one of them has a typo as you are setting the same array twice), and write
char str1[MAX_LINE_LEN] = {0};
&c. instead. That will zero-initialise all the elements in the array. This is superior to using memset:
It reduces the possibility for bugs such as the one you have.
str1 and str2 are never in an uninitialised state.
You don't have to repeat the length of the array or conjure an expression (e.g. sizeof idioms) to impute it.
Reference for (3): https://en.wikipedia.org/wiki/Don%27t_repeat_yourself

Fill char *array from 0 to x [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
i have a problem with a char *array in c (gcc linux)
on debian it works, but on another systems (yocto,raspbian) come a segmentation fault
The working Code in Debian:
char *myarray;
for (i=0;i<999;i++){
printf(myarray, "%i", i);
//do something with string to compare in file
}
But this Code fault on another Systems, i have tried to make a Array:
char *myarray[999]={"0","1","2"};
for (i=0;i<999;i++){
//do something with string[i] to compare in file
}
This Code also works but i dont like to fill a array from hand to "999"
I haven't found a method to make a char *string[arr] from "0"-"999" in a loop
Well , you can use sprintf-
char *array[1000];
for(int i=0;i<1000;i++){
array[i]=malloc(10*sizeof(**array)); //allocate memory to pointer
if(array[i]!=NULL){ //check return of malloc
sprintf(array[i],"%d",i);
}
}
Note- Just remember to free the allocated memory.
It's very unclear what you're after.
If you want to build an array holding the strings "0" through "999", you can do it using snprintf():
char array[1000][4]; /* Wastes some space, but not a great deal. */
for(int i = 0; i < 1000; ++i)
snprintf(array[i], sizeof array[i], "%d", i);
then you can print e.g. 452 like so:
printf("452 is %s\n", array[452]);

Counting number of items in an array in C [closed]

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 7 years ago.
Improve this question
I keep getting the output of 100 when I do what everyone else online has been posting about:
int total = sizeof(num)/sizeof(int);
It doesn't seem to work for me. Here's my code:
int main() {
static int num[100];
int totalNum = sizeof(num)/sizeof(int);
return 0;
}
void readNumbers(int* num) {
int i = 0;
FILE *fp;
fp = fopen("/Users/Documents/hello.txt", "r");
if (fp == NULL) {
printf("Could not load file");
exit(0);
}
/* Loads numbers into num array */
int number;
while(fscanf(fp, "%d", &number) > 0) {
num[i] = number;
i++;
}
}
My output is 100 so I'm assuming there isn't anything that is inserted into the num array? And if I print out sizeof(num) it gives me a hundred; 4 bytes * 100 = 400.
Here is what is in hello.txt:
14 21 39 48 109 3882
Unlike arrays in other languages (that can grow and shrink, and will tell you how many elements the array currently contains), a C array is just a simple block of memory that has a fixed size. You declared an array that can hold 100 elements, and that's all sizeof is going to tell you.
If you want to know how many numbers you've put in the array, then you have to keep track of that in a separate variable. The array itself doesn't contain that information.

How to read information from a certain line in C? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a results.txt file and on the seventh line I have numbers in form like:
3 5 6 1 9 7 4
I want to gather information how many of them > 5 and how many of them < 5.
How can I do this process for all of them?
By the way, the seventh line is the last line of the file.
Just read one line at a time and count. When you reach 7, that's your seventh line. Use fgets. Once you have the line you can use strtol in a loop to read each value as an integer.
Reference: fgets, strtol
To skip 1 line in the input file:
fscanf(f, "%*[^\n]\n");
To read 1 number from the file:
int number;
fscanf(f, "%d", &number);
To compare a number with 5:
if (number < 5)
{
...
}
P.S. The site http://www.cplusplus.com has some examples for the basic stuff you need. That site is dedicated to C++ but at your level there so little difference between C and C++, you can use the examples for your work (if you understand them).
Example: fscanf (at the bottom of the page)
#include <stdio.h>
#define LINE_MAX 1024
int main() {
int line_count = 7;
int fd = open('file', r);
int smaller_than_five = 0, bigger_than_five = 0;
int number;
while (line_count != 0) {
fgets(input_line, LINE_MAX, fd);
line_count--;
}
while(sscanf(input_line, "%d", &number) != EOF) {
if (number > 5) bigger_than_five++;
else if (number < 5) smaller_than_five++;
}
/*
* Now you have:
* smaller_than_five which is the count of numbers smaller than five
* bigger_than_five which is the count of numbers bigger than five
*/
return 0;
}
This works when the numbers are on seventh line. If they are on the last (but could be second or 51st), you'll have to change the first while to read while you have not reached the end.

Resources