473,382 Members | 1,165 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

From file to char* array

Hi,

I've char* array that I defined like char *str[150]. I want to read
from a file, that contains names in each row, and assign them to my str
char * array.

m is a char array, f is a file pointer and counter is my variable that
contains number of names in my file;

When I write;

while(fgets(m,100,f)!=NULL) {
printf("%s",m)
}

code. It gets and writes all my names onto screen but;

When I recode it like;

while(fgets(m,100,f)!=NULL) {
str[counter]=m;
counter--;
}

and try print str[1] ve str[2] to screen It always print my last
elements for 2 times.

For example:

File: John, Alp, Liz, Sema

First code writes;
John, Alp, Liz, Sema

With second code and printfs:
Sema, Sema

How can I fix it? Thanks so much...

Dec 8 '06 #1
8 3043
OziRus wrote:
Hi,

I've char* array that I defined like char *str[150]. I want to read
from a file, that contains names in each row, and assign them to my str
char * array.
<snip>

#include <stdio.h>
#include <stdlib.h>

#define MAX_NAMES 150
#define MAX_NAME_LENGTH 256

int main(int argc, char **argv) {
FILE *f;
char *names[MAX_NAMES];
int cnt;

/* open file */
if(argc < 2) {
fprintf(stderr, "No file specified.\n");
exit(EXIT_FAILURE);
}
else {
f = fopen(argv[1], "r");
if(f == NULL) {
fprintf(stderr, "Unable to open file: %s\n", argv[1]);
exit(EXIT_FAILURE);
}
}

/* allocate memory for names */
for(cnt = 0; cnt < MAX_NAMES; cnt++) {
if((names[cnt] = malloc(MAX_NAME_LENGTH * sizeof *names)) == NULL)
{
fprintf(stderr, "No memory.\n");
exit(EXIT_FAILURE);
}
}

/* read lines into memory */
for(cnt = 0; cnt < MAX_NAMES; cnt++) {
if(fgets(names[cnt], MAX_NAME_LENGTH, f) == NULL && ferror(f)) {
fprintf(stderr, "Error reading file: %s\n", argv[1]);
for(cnt = 0; cnt < MAX_NAMES; cnt++) free(names[cnt]);
exit(EXIT_FAILURE);
}
}

/* print what we've read in from file */
for(cnt = 0; cnt < MAX_NAMES; cnt++)
fprintf(stdout, "%s", names[cnt]);
fflush(stdout);

for(cnt = 0; cnt < MAX_NAMES; cnt++) free(names[cnt]);
return EXIT_SUCCESS;
}

Dec 8 '06 #2
Thanks. But I still can't understand why

while(fgets(m,100,f)!=NULL) {
str[counter]=m;
counter--;
}

doesn't work...

Dec 8 '06 #3
OziRus said:
Thanks. But I still can't understand why

while(fgets(m,100,f)!=NULL) {
str[counter]=m;
counter--;
}

doesn't work...
str[counter] = m; does not allocate fresh storage for a copy of your string.
It merely points str[counter] at your existing buffer. So you end up with a
whole bunch of pointers all pointing to the same place. And if you give any
one of those pointers to printf, you'll get the same data printed out.

As santosh has demonstrated, you can fix this by allocating sufficient
storage for each line of data, and by then copying your data into it.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 8 '06 #4

OziRus wrote:
Thanks. But I still can't understand why

while(fgets(m,100,f)!=NULL) {
str[counter]=m;
counter--;
}

doesn't work...
The line
fgets(m,100,f)
reads at most 100 bytes of data from FILE f, and places that data into
the character buffer m, overwriting anything that was previously stored
in buffer m

The line
str[counter]=m
takes the address of the first byte of the buffer m (effectively) and
stores that address in str[counter]

It /does not/ copy the contents of the buffer m into str[counter]. For
that, you would have to use something like strcpy()

Once your while loop completes, you have a number of str[] entries all
pointing to the same buffer m

When you print each str[] entry, you print the current contents of
buffer m, which contains the /last/ value retrieved by fgets()

HTH
--
Lew

Dec 8 '06 #5
Thank you so much!

Richard Heathfield yazdi:
OziRus said:
Thanks. But I still can't understand why

while(fgets(m,100,f)!=NULL) {
str[counter]=m;
counter--;
}

doesn't work...

str[counter] = m; does not allocate fresh storage for a copy of your string.
It merely points str[counter] at your existing buffer. So you end up with a
whole bunch of pointers all pointing to the same place. And if you give any
one of those pointers to printf, you'll get the same data printed out.

As santosh has demonstrated, you can fix this by allocating sufficient
storage for each line of data, and by then copying your data into it.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 8 '06 #6
OziRus wrote:
Thank you so much!
Please don't top-post. Your replies belong following or interspersed
with properly trimmed quotes. See the majority of other posts in the
newsgroup, or:
<http://www.caliburn.nl/topposting.html>
Dec 8 '06 #7
On 8 Dec 2006 09:24:34 -0800, "santosh" <sa*********@gmail.comwrote:
>OziRus wrote:
>Hi,

I've char* array that I defined like char *str[150]. I want to read
from a file, that contains names in each row, and assign them to my str
char * array.
<snip>

#include <stdio.h>
#include <stdlib.h>

#define MAX_NAMES 150
#define MAX_NAME_LENGTH 256

int main(int argc, char **argv) {
FILE *f;
char *names[MAX_NAMES];
int cnt;

/* open file */
if(argc < 2) {
fprintf(stderr, "No file specified.\n");
exit(EXIT_FAILURE);
}
else {
f = fopen(argv[1], "r");
if(f == NULL) {
fprintf(stderr, "Unable to open file: %s\n", argv[1]);
exit(EXIT_FAILURE);
}
}

/* allocate memory for names */
for(cnt = 0; cnt < MAX_NAMES; cnt++) {
if((names[cnt] = malloc(MAX_NAME_LENGTH * sizeof *names)) == NULL)
Why use malloc()? The size of names[cnt] is certainly not unknown or
even "dynamic". Both MAX_NAME_LENGTH and sizeof *names are
compile-time constants.

Why not just declare an appropriate array with either automatic or
static storage duration? If you did that, it:

1. Would free you from having to free().
2. Would result in a smaller memory footprint (less code).
3. Might make the difference between running or not on a non-hosted
environment. Resources can get pretty constrained on, for example,
some embedded systems. Such implementations might not even
*practically* support malloc().
4. Might unnecessarily violate coding standards (thou shall not use
dynamic memory) that are applicable to, for example, safety-critical
systems.

--
jay
>{
fprintf(stderr, "No memory.\n");
exit(EXIT_FAILURE);
}
}

/* read lines into memory */
for(cnt = 0; cnt < MAX_NAMES; cnt++) {
if(fgets(names[cnt], MAX_NAME_LENGTH, f) == NULL && ferror(f)) {
fprintf(stderr, "Error reading file: %s\n", argv[1]);
for(cnt = 0; cnt < MAX_NAMES; cnt++) free(names[cnt]);
exit(EXIT_FAILURE);
}
}

/* print what we've read in from file */
for(cnt = 0; cnt < MAX_NAMES; cnt++)
fprintf(stdout, "%s", names[cnt]);
fflush(stdout);

for(cnt = 0; cnt < MAX_NAMES; cnt++) free(names[cnt]);
return EXIT_SUCCESS;
}
Dec 9 '06 #8
On 8 Dec 2006 08:46:41 -0800, "OziRus" <ca************@gmail.com>
wrote:
<snip>
while(fgets(m,100,f)!=NULL) {
str[counter]=m;
counter--;
}
You almost certainly had and wanted counter++ there. Unless you knew
in advance the number of lines you will read, or at least a safe upper
bound, and from the rest of your discussion you don't.

Assuming so, the only problem you have is reusing/sharing the buffer
m, as already answered by others.

If you really have counter-- and are at any time decrementing below
zero, then that is a second problem.

- David.Thompson1 at worldnet.att.net
Dec 26 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Venkat | last post by:
Hi All, I need to copy strings from a single dimensional array to a double dimensional array. Here is my program. #include <stdio.h> #include <stdlib.h>
39
by: Joe Laughlin | last post by:
If I have a character array with "/some/file/directory/file_name", are there any functions / libraries that I could use to separate the directory ("some/file/directory") from the file name...
1
by: john | last post by:
Relatively new to C coding, so any help would greatly be appreciated. I'm having problems try to return my string array from my parsing function. When I do a printf I am getting the correct value...
5
by: Stephen Cawood | last post by:
I'm trying to use a C++ .lib from C# (I tried the Interop group will no results). I have a working wrapper DLL (I can get back simple things like int), but I'm having issues dealing with an array...
0
by: Holly | last post by:
I copied this code that works to connect into Unix. I am looking for a way to get it to work with a secure Unix box. Anyone have any insights on how to do this? I am trying to build an sftp...
2
by: Potiuper | last post by:
Question: Is it possible to use a char pointer array ( char *<name> ) to read an array of strings from a file in C? Given: code is written in ANSI C; I know the exact nature of the strings to be...
7
by: theballz | last post by:
Hi, I am learning c programming and come across a problem i cant seem to solve. I have a file which i wish to parse and put certain lines (which do not contain a hash character) into an array...
6
by: Kinbote | last post by:
Hi, I'm trying to make a function that opens a file, reads it in line by line, puts each line into an malloc'd array, and returns the array. I suspect I'm going about it in an atypical fashion, as...
13
by: rohit | last post by:
Hi All, I am new to C language.I want to read integers from a text file and want to do some operation in the main program.To be more specific I need to multiply each of these integers with another...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.