Get a certain number of elements into an Array - c

This is my code so far:
#include "stdafx.h"
#define SIZE 200
int _tmain(int argc, _TCHAR* argv[])
{
FILE * ifp = NULL;
int inputArray[SIZE];
int i, j;
int c;
ifp = fopen("testfile.txt", "r");
for (i = 0; i <= SIZE; ++i)
fscanf(ifp, "%d", &inputArray[i]);
/*fscanf(ifp, "%d", */
for (i = 0; i <= SIZE; i++)
printf("%d", inputArray[i]);
return 0;
}
So I have a file that has nnumbers in it like:
3
5 5 3
6
3 2 6 4 1 1
The code above seems to work in getting the numbers into an array like 3 5 5 3 6 3 2...etc.
But then, the array size is 200. So the rest of the space not used in the array isn't just blank. It has a huge, weird numbers in it
so when I print it out, it it prints
35536326411 -858993460 -858993460
it prints that -858993460 to what I assume is about 200 times.
I'm a total noob in C and in programming. I asked the professor about the array size and he said just set it to a large number like 100 or 200 because trying to set the size of the array to a variable that can be changed (or something to that concept) is complicating and isn't at our level quite yet.
I need to do math with these numbers and I don't want to include those -858993460 things in my calculations. How would I determine where in the array is the last element that was actually declared?
Someone please point me into the right direction...

for (i = 0; i <= SIZE; ++i)
should be
for (i = 0; i < SIZE; ++i)
Else you have array out of bound access which will lead to undefined behavior.
for (i = 0; i < SIZE; ++i)
{
if(fscanf(ifp, "%d", &inputArray[i]) != 1)
break;
}
Set all elements to 0 using
memset(array,0,sizeof(array));

You can check the return value of fscanf() and once it returns failure [return !=1], you should stop scanning anymore.
Further, you can use that i-1 value for printing valid elements.
Also, you should change your loop limit to i < SIZE to avoid off-by-one error.
Then, you can initialize the local variables to avoid them having garbage values. You can use memeset() or initializer-lists to get that part done.

Don't define SIZE, make it a variable that will contains real count of number in file after reading.
size_t SIZE = 0;
for (SIZE = 0; ; ++SIZE)
{
if (fscanf(ifp, "%d", &inputArray[i]) == EOF)
break;
}

Related

C - Reading Till The EOF, Getting Additional Addresses and Numbers (Array)

So, I have a File full of numbers:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
The case is, I don't know the exact number of numbers in this file, so I don't know the exact size of array I will need to write this file info in to this array.
I just gave array much bigger size than I need and I will show you the output, partially it does its job.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#define ARR_SIZE 30
int main(void){
FILE *fp;
int array[ARR_SIZE];
fp = fopen("C:/project/project.txt", "r");
printf("Numbers: ");
for(int i = 0; i < ARR_SIZE; i++){
fscanf(fp, "%d", &array[i]);
}
for(int j = 0; j < ARR_SIZE; j++){
printf("\n%d", array[j]);
}
fclose(fp);
return 0;
}
I am just trying to do standard things, opening file, reading file with for loop, writing all this info to array and outputting array.
Here is the output I get, I understand it is because of the size, but can you tell me how to limit all of these? Easiest way?
Output:
Numbers:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
4199136
0
4200896
6422240
6422296
6422476
1998244384
592257989
-2
1998220218
1998220461
4200896
6422368
4200987
4200896
I have array size 30 and numbers in the file 15, first 15 is okay, it is exactly what I need, but I don't need those number after it...
You need a stop-condition for the loop that reads from the file. One option is to stop when you can't scan an item. Use the return value from fscanf to detect that.
When you do the printing only print the number of items actual scan'ed.
Try
for(int i = 0; i < ARR_SIZE; i++){
if (fscanf(fp, "%d", &array[i]) != 1) break; // Stop if the scan fails
}
for(int j = 0; j < i; j++){ // ARR_SIZE replaced by i
printf("\n%d", array[j]);
}
BTW: You should check that fp is valid just after the file open.

Redirecting a file from stdin, using fgets() to read information to array

int main() {
#define MEMSIZE 100
int memory[MEMSIZE] = {0};
int i = 0;
char *temp = malloc(sizeof(100));
fgets(temp, MEMSIZE, stdin);
for (i = 0; i < (sizeof(memory)/sizeof(int)); i++) {
memory[i] = temp[i];
}
for (n = 0; n < 10; n++) { // Print contents
printf("%d - %d\n", n, memory[n]);
}
}
So today I have what seems to be a very simple question. I am taking a file from stdin, using:
./a.out < filename
My main goal is to take in the numbers provided in the file, and store them into a 1 dimensional array. My current use of fgets() works correctly, reading in line one and copying those elements into my 1D array (their ASCII values converted to int). Now, to read in my next lines, if I call fgets() again, the next line is read but it is then stored in the same place as the first values, thus overwriting them in my array in position 0-3. These values need to be stored successively in my array until EOF.
The file is in the format:
1234
5678
...
#include <stdio.h>
#define MEMSIZE 100
int main() {
int memory[MEMSIZE] = {0};
int i,n;
for (i = 0; i <MEMSIZE; i++){
if(fscanf(stdin,"%d", (memory+i))==EOF){
break;
}
}
//i is the number of ints you got
for (n = 0; n < i; n++) { // Print contents
printf("%d - %d\n", n, memory[n]);
}
return 0;
}
I dont see a reason to use dynamic allocation over here as a temp variable.
If the file is list of numbers, just read as a number, no need for fgets over here, if you still want to read it as a string, have a look at atoi func
sizeof(memory)/sizeof(int)= (sizeof(int)*MEMSIZE)/sizeof(int)= MEMSIZE
You shouldn't just loop MEMSIZE times, you need to know when it EOF
I dont know why you assumed in the printing loop that 10 is enough, i changed it to i which is number of elements
You didnt define n
I hope that i helped.

Read integers from file in C

1 2 3 4 5
1 2 3 4 5
1 2 3
2 5 7 8 9 8
I'm a beginner of C and I want to write a small program but I have this problem.
The problem is: if there is a file contains integers, the number of integers of each line is different but all within the maximum number of integers.
For example the integers above, the maximum number of integers for each line is 6, each line could have from 1 to 6 integers. The maximum number of integers will also change for each file.
How to store these numbers into a 2D array? Or store the integers into arrays line by line. (Don't worry about the empty values)
I have tried to use fscanf, but I don't know how to define the number of integers of each reading.
================================
Thanks everyone for the generous help, I've figured out using Joachim Pileborg's idea.
#define MAX_SIZE_BUFFER 1000
FILE *file;
int len = MAX_SIZE_BUFFER;
char sLine[MAX_SIZE_BUFFER];
int i, j, maxnumber = 6;
int *numbers, *temp;
char *sTok;
numbers = (int *) malloc(sizeof(int) * maxnumber);
for (i = 0; i < maxnumber; i++) {
numbers[i] = -1;
}
while (fgets(sLine, len, file) != NULL) {
i = 0;
sTok = strtok(sLine, " ");
while (sTok != NULL) {
numbers[i] = atof(sTok);
sTok = strtok(NULL, " ");
i++;
}
/* This temp stores all the numbers of each row */
temp = (int *) malloc(sizeof(int) * i);
for (j = 0; j < i; j++) {
temp[j] = numbers[j];
}
}
The code above is not completed, but it's the idea how I do this.
One way to solve your problem is to start by reading line by line (using e.g. fgets). Then for each line you need to separate the "tokens" (integers) which you can do with e.g. strtok in a loop. Finally, convert each "token" string to an integer using e.g. strtol.
let's try: fscanf(fp, "%d", value)
fp : file pointer.
"%d": format of the value that you want to read (it can be %c, %f, ...).
value: use it to keep the value you just read from the file.
Of course you should put it into the loop if you want to read all content in the file. EOF is the condition to break the loop.

Issues with reading words from a text file into 2d Array

I recently started a program in which I have to sort a list of guests, but the overall problem details are irreverent for the issue I'm having.
Well, I want to scan in first and last names from a file SEPARATELY, which I know you do by scanning them as strings. However, we just started using strings and I'm having a little brain fart and I've searched places but I can't figure out how to do so. I'm also having trouble structuring the array inside the for loops. My mind has been totally out of school since Skyrim came out :). Here's the input text file:
//First number is the amount of families on the list, second number is the room capacity, ignore that for now.
10 30
//Format = First Name, Last Name, Number of Family Members (ignore), Priority Level (ignore)
BEN JOHNSON 4 2
DOUG ESPINOSA 3 2
SARAH TELLINGER 5 3
GRANT THOMPSON 5 2
JENNIFER WEST 7 6
JACKSON JOHNSON 1 5
MARTY MCFLY 4 1
ELIZABETH JAMES 2 6
MICKEY MOUSE 2 4
RAJ SHAH 2 5
Here's my code so far: Assume MAX_FAMILY_MEMBERS = 10 and MAX_NAME_LENGTH = 20
void Read_First_Name(FILE *ifp, char First_Name[//Assume MAX_FAMILY_MEMBERS is here][MAX_NAME_LENGTH]){
int i, j;
for(i = 0; i < MAX_FAMILY_MEMBERS; i++)
{
for(j = 0; j < MAX_NAME_LENGTH; i++)
{
fscanf("%s", First_Name[i][j]);
}
}}
I'm sure this is most likely wrong but I'm quite confused and out of it. If there are any questions about my program please ask.
Its easy if you use fgets with sscanf in one loop like
char line[100], firstnames[100][100], famnames[100][100];
int counter=0;
while( fgets(line,100,yourfilepointer) )
if( sscanf(line,"%s%s",firstnames[counter],famnames[counter])==2 )
++counter;
...
while( counter-- )
printf("%s %s\n",firstnames[counter],famnames[counter]);
void Read_And_Store(FILE *ifp, int FAMILIES_KNOWN, char First_Name[][MAX_NAME_LENGTH], char Last_Name[][MAX_NAME_LENGTH], int Family_Members[], int Priority[]){
int i;
for(i = 0; i < FAMILIES_KNOWN - 1; i++)
{
fscanf(ifp, "%s", First_Name[i]);
fscanf(ifp, "%s", Last_Name[i]);
fscanf(ifp, "%d", &Family_Members[i]);
fscanf(ifp, "%d", &Priority[i]);
}}
Here's what I did and it works fine when I print it out. However, I've tried a bunch of stuff trying to sort the printed list by priority level, but none of them are successful... any ideas? After I get the sort down the rest is just basic logic and swapping.
I Presume you want to sort the families basing on their priority level. In the code you wrote,
Your fscanf syntax is incorrect. Go through the syntax once more.
for(i = 0; i < MAX_FAMILY_MEMBERS; i++)
{
for(j = 0; j < MAX_NAME_LENGTH; i++)
{
fscanf("%s", First_Name[i][j]);
}
}
It is good that you want to read line by line (family by family) but how you read each family is improper.
%s format specifier reads an entire string until it encounters a space.
so that second for loop is very messy.
I will slightly change the code, you can improve on it and write your own logic
#define NUMBEROFFAMILIES 10
#define FAMILYNAMELENGTH 20
char firstName[NUMBEROFFAMILIES][FAMILYNAMELENGTH]; // to store first name
char secondName[NUMBEROFFAMILIES][FAMILYNAMELENGTH]; // to store second name
int familtyPriority[NUMBEROFFAMILIES][1]; // to store priority
int i, j;
for(i = 0; i < MAX_FAMILY_MEMBERS; i++){
fscanf(ifp,"%s",firstName[NUMBEROFFAMILIES]); // read first name
fscanf(ifp,"%s",secondName[NUMBEROFFAMILIES]); // read second name
fscanf(ifp,"%d", &j); // Ignore family members count
fscanf(ifp,"%d", &familtyPriority[NUMBEROFFAMILIES][1]); // family priority
}
EDITED FOR THE NEXT QUESTION
You want to sort based on the priority level.
int familtyPriorityCopy[NUMBEROFFAMILIES][1]; // to store priority
int familyOrder[NUMBEROFFAMILIES][1]; // to store the proper order.
// initialize them
for (i=0;i<NUMBEROFFAMILIES;i++){
familtyPriorityCopy[i][1] = familtyPriority[i][1];
familyOrder[i][1] = i;
}
// sorting [insertion sort]
for (i=1;i<NUMBEROFFAMILIES;i++){
for (j=0;j<i;j++){
if (familtyPriorityCopy[j][1] < familtyPriorityCopy[i][1]){
swap(familtyPriorityCopy[i][1],familtyPriorityCopy[j][1]);
swap(familyOrder[i][1], familyOrder[j][1]);
}
}
}
At the end, familtyPriorityCopy array is sorted. But this is not what is important. familyOrder array is what points to the correct order. We will use this array to print them in the right order.
for(i = 0; i < MAX_FAMILY_MEMBERS; i++){
printf("%s",firstName[familyOrder[i][1]][1]); // read first name
printf("%s",secondName[familyOrder[i][1]][1]); // read second name
printf("%d", familtyPriority[familyOrder[i][1]][1]); // family priority
}

Reading an array of integers and printing them out

I'm learning C on my own and doing a few exercises. The following code reads in an
array of integers from the user. The integers are printed out when the user types in a "0" or when the array is filled. Now the problem is the output. When I type in "0" after I have typed in 3 digits e.g. 1 2 3 the output is the following: 1 2 3 -858993460 -858993460. I am not sure why I get the value "-858993460" but I have already found a solution to avoid it. Now my question is what the values mean and if there is a smarter solution than mine which is presented below as comments.
#include <stdio.h>
#include <string.h>
#define arraylength 5
int main ()
{
//const int arraylength = 21; //alternative possibility to declare a constant
int input [arraylength] ;
int temp = 0;
//int imax = 0;
printf("Please type in a your digits: ");
for (int i = 0; i < arraylength; i++)
{
scanf("%d", &temp);
if ( temp !=0)
{
input[i]= temp;
//imax= i;
}
else
{
//imax= i;
break;
}
if (i < arraylength-1)
printf("Next: ");
}
for (int i =0; i < arraylength; i++ ) // switch arraylength with imax
{
printf("%d", input[i]);
}
getchar();
getchar();
getchar();
}
This happens because irrespective of when the 0 input is given you print all 5 numbers:
for (int i =0; i < arraylength; i++ )
To fix this you can print only the number(s) user entered before entering a 0 by running a loop from 0 to i:
for (int j =0; j < i; j++ )
Those 2 numbers are the garbage that was left in the memory locations for the last 2 parts of your array. You never initialise those when you only input 3 numbers, so when you go through and print all 5 elements in the array, it prints whatever garbage was in the memory.
You print all integers in array which is size of arraylength = 5. So you get 5 integers in output. As you didn't initialize array, you get uninitilized values as 4th and 5th elements of array. You can use memset(&input, 0, arraylength*sizeof(int)); to set initials values in array to 0.

Resources