Thread: how to read strings?

  1. #1
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391

    how to read strings?

    Here's a bit of my code:

    Code:
      
    struct data {
            int month, day, year, hour, minute, number;
            char string1[2];
            char string2[FILENAMELENGTH];
            char stringstorage[LINELENGTH];  /* Used to store strings from file */
        } LineData[NUMBEROFFILES];
    
    while( (fgets(LineData[count].stringstorage, LINELENGTH , openfile) != NULL) && (count < NUMBEROFFILES) )
        {
            /* code to process string */
            count++;
            lastfilecount = count;
        }
    I would like to read the strings in the array(or even a pointer), and seperate the data in the string.

    I am thinking something similar to:

    Code:
    fscanf(openfile, "%d/%d/%d %d:%d %s %d %s", &LineData[count].month, &LineData[count].day,
                                   &LineData[count].year, &LineData[count].hour, &LineData[count].minute,
                                  LineData[count].string1, &LineData[count].number, &LineData[count].string2);
    but using the array "LineData[count].stringstorage" as a source, instead of using a file.

    I know how to read strings from keyboard input(gets), and files(fscanf), but strangely enough, I don't know how to read strings which sit in an array, or a pointer. And my C book isn't of any help.

    I did a search in the forums, but can't find anything that I could use. Maybe because I am not using the right keywords.

    Thanks.
    Last edited by happyclown; 01-17-2009 at 10:28 PM. Reason: formatted the code to fit the screen
    OS: Linux Mint 13(Maya) LTS 64 bit.

  2. #2
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    One way to print a string in an array of char's would be to loop through the array, and print it char by char, with putchar(index).

    Another way would be:
    Code:
    printf("%s", array);
    Or for a 2 dimensional array:

    Code:
    printf("%s", array[indexYouWant]);
    This requires both strings to have an end of string marker on them, to work right.

    This just uses the fact that the array name points to the base of the array itself (or the row, in the second case).

  3. #3
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Thanks Adak.

    I don't have a problem with reading and printing arrays or pointers.

    This may be a better wording of what I want to achieve:

    I would like to read("process") a string, and the string does not come from the keyboard(stdin), or a file(stream). The string sits in an array, or a pointer.

    My problem is that I don't know how to manipulate a string, and these string functions don't help.

    EDIT: Here's the contents of a file that I want to read:

    12/16/2008 10:21 AM 969 bobthebuilder.html
    08/14/2008 06:13 AM 10,261 purplebarney.html
    08/14/2008 06:08 AM 12,083 mrpotatohead.html
    08/09/2008 05:10 PM 4,076 spongebob.html
    08/09/2008 05:41 PM 3,531 thewiggles.html
    12/06/2008 03:04 PM 1,016 lindsaylohan.html

    And here's attempt, which clearly does not work.

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    #define NUMBEROFFILES 1000
    #define FILENAMELENGTH 40
    #define LINELENGTH 100
    
    int main( void )
    {
        int count, lastfilecount;
        FILE *openfile;
    
        struct data {
            int month, day, year, hour, minute, number;
            char string1[2];
            char string2[FILENAMELENGTH];
            char stringstorage[LINELENGTH];  /* Used to store strings from file */
        } LineData[NUMBEROFFILES];
    
        /* Test to see that the file "directorylisting.txt" can be opened for reading. */
    
        if( (openfile = fopen("directorylisting1.txt", "rt")) == NULL)
        {
            perror("\ndirectorylisting1.txt");
            exit( EXIT_FAILURE );
        }
    
        /* Read one line at a time into structure */
    
        count = 0;
    
        while( (fgets(LineData[count].stringstorage, LINELENGTH , openfile) != NULL)
                                                            && (count < NUMBEROFFILES) )
        {
            fscanf(openfile, "%d/%d/%d %d:%d %s %d %s", &LineData[count].month, &LineData[count].day,
                                &LineData[count].year, &LineData[count].hour, &LineData[count].minute,
                                LineData[count].string1, &LineData[count].number, &LineData[count].string2);  
    
            count++;
            lastfilecount = count;
        }
    
        fclose(openfile);
    
        /* Print the structures */
    
        for( count = 0; count < lastfilecount; count++)
        {
            printf("%d/%d/%d %d:%d %s %d %s\n", LineData[count].month, LineData[count].day, LineData[count].year,
                  LineData[count].hour, LineData[count].minute, LineData[count].string1,
              LineData[count].number, LineData[count].string2);
        }
    
        return 0;
    }
    The code in red should not be there, but it's just to give people an idea of what I want to achieve.
    Last edited by happyclown; 01-17-2009 at 11:19 PM. Reason: formatted code to fit screen
    OS: Linux Mint 13(Maya) LTS 64 bit.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    sscanf
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    This is what I was suggesting:

    Code:
    #include <stdio.h>
    
    char array[10][20] = {
     { "George" },
     { "Giorgina" },
     { "Gillermo" },
     { "Gilliam" },
     { "Gladstone"},
     { "Goodman" },
     };
    
    int main(void)
       {
       int i;
       for(i = 0; i < 10 ; i++)
          printf("%s \n", array[i]);
    
       printf("\n\n\t   Program Complete - Press Any Key to Continue ");
       i = getchar();
       return 0;  
       }
    In your case it might be linedata[i].string1 and linedata[i].string2, instead of array[i]
    Last edited by Adak; 01-18-2009 at 12:25 AM.

  6. #6
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Quote Originally Posted by MK27 View Post
    sscanf
    This was the function that I was looking for, thanks.

    But there's a slight problem that I'm having.

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    #define NUMBEROFFILES 1000
    #define FILENAMELENGTH 40
    #define LINELENGTH 100
    
    int main( void )
    {
        int count, lastfilecount;
        FILE *openfile;
    
        struct data {
            int month, day, year, hour, minute, number;
            char string1[2+1];
            char string2[FILENAMELENGTH];
            char stringstorage[LINELENGTH];  /* Used to store strings from file */
        } LineData[NUMBEROFFILES];
    
        /* Test to see that the file "directorylisting.txt" can be opened for reading. */
    
        if( (openfile = fopen("directorylisting1.txt", "rt")) == NULL)
        {
            perror("\ndirectorylisting1.txt");
            exit( EXIT_FAILURE );
        }
    
        /* Read one line at a time into structure */
    
        count = 0;
    
        while( (fgets(LineData[count].stringstorage, LINELENGTH , openfile) != NULL) && (count < NUMBEROFFILES) )
    
        {
            sscanf(LineData[count].stringstorage, "%d/%d/%d %d:%d %s %d %s", &LineData[count].month, &LineData[count].day,
                              &LineData[count].year, &LineData[count].hour, &LineData[count].minute,
                             LineData[count].string1, &LineData[count].number, &LineData[count].string2);
    
            count++;
            lastfilecount = count;
        }
    
        fclose(openfile);
    
        /* Print the structures */
    
        for( count = 0; count < lastfilecount; count++)
        {
            printf("%d/%d/%d %d:%d %s %d %s\n", LineData[count].month, LineData[count].day,
    
    LineData[count].year,
     LineData[count].hour, LineData[count].minute, LineData[count].string1,
                              LineData[count].number, LineData[count].string2);
        }
    
        return 0;
    }
    This is what I'm trying to read:

    12/16/2008 10:21 AM 969 bobthebuilder.html
    08/14/2008 06:13 AM 10,261 purplebarney.html
    08/14/2008 06:08 AM 12,083 mrpotatohead.html
    08/09/2008 05:10 PM 4,076 spongebob.html
    08/09/2008 05:41 PM 3,531 thewiggles.html
    12/06/2008 03:04 PM 1,016 lindsaylohan.html

    This is the output:

    12/16/2008 10:21 AM 969 bobthebuilder.html
    8/14/2008 6:13 AM 10 ,261
    8/14/2008 6:8 AM 12 ,083
    8/9/2008 5:10 PM 4 ,076
    8/9/2008 5:41 PM 3 ,531
    12/6/2008 3:4 PM 1 ,016
    0/0/0 0:0 0


    The comma in the numbers are causing the rest of the line to be chopped off.

    I'll try to figure this one out, and will post back here in a few days if I still need help.

    Thanks for everybody's help.
    Last edited by happyclown; 01-18-2009 at 02:30 AM. Reason: formatted code to fit screen
    OS: Linux Mint 13(Maya) LTS 64 bit.

  7. #7
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Ok, I think I might be heading in the right direction.

    Code:
    sscanf(LineData[count].stringstorage, "%d%/%d/%d %d:%d %s %d,%d %s", &LineData[count].month,
                    &LineData[count].day, &LineData[count].year, &LineData[count].hour,
                    &LineData[count].minute, LineData[count].string1, &LineData[count].number,
                    &LineData[count].number1, &LineData[count].string2);
    This is what I'm trying to read:

    12/16/2008 10:21 AM 969 bobthebuilder.html
    08/14/2008 06:13 AM 10,261 purplebarney.html
    08/14/2008 06:08 AM 12,083 mrpotatohead.html
    08/09/2008 05:10 PM 4,076 spongebob.html
    08/09/2008 05:41 PM 3,531 thewiggles.html
    12/06/2008 03:04 PM 1,016 lindsaylohan.html

    Output:

    12/16/2008 10:21 AM 969,0
    8/14/2008 6:13 AM 10,261 purplebarney.html
    8/14/2008 6:8 AM 12,83 mrpotatohead.html
    8/9/2008 5:10 PM 4,76 spongebob.html
    8/9/2008 5:41 PM 3,531 thewiggles.html
    12/6/2008 3:4 PM 1,16 lindsaylohan.html


    1. The first line is still wrong.

    2. And notice the 0 missing from line 3 & 4? What do you suppose is going on there?

    I am guessing the program thinks the comma in the numbers is actually a string.

    I had previously tried to exclude the comma with:

    Code:
    sscanf(LineData[count].stringstorage, "%d%/%d/%d %d:%d %s %[^,]d %s", &LineData[count].month,
                &LineData[count].day, &LineData[count].year, &LineData[count].hour,
                &LineData[count].minute, LineData[count].string1, &LineData[count].number,
                &LineData[count].number1, &LineData[count].string2);
    But that resulted in partial garbage output.

    Time to go to sleep! Goodnight! ZZZzzzzzzzzz.....
    Last edited by happyclown; 01-18-2009 at 01:10 PM. Reason: typo
    OS: Linux Mint 13(Maya) LTS 64 bit.

  8. #8
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Well, I still can't get this program to work.

    Here's my code. Please ignore the block of comments in the middle. That's just for my own use.
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    #define NUMBEROFFILES 1500
    #define LINELENGTH 150
    #define FILENAMELENGTH 40
    #define BEGINNINGOFHTMLLIST 5  /* First file in html list */
    
    int main( void )
    { 
        int lastfilenumber;
        FILE *openfile, *comma;
        int counter;
    
    	struct data {
            int month, day, year, hour, minute;
            char string1[2+1];
    		int number1, number2;
            char string2[FILENAMELENGTH];
            char stringstorage[LINELENGTH];  /* Used to store strings from file */
        } LineData[NUMBEROFFILES];
    
        /* Get a list of files in the directory "testwebsite", and redirect the
        output to a file called "directorylisting.txt". */
    
        // system("dir c:\\testwebsite\\*.html > directorylisting.txt");
    
        /* Test to see that the file "directorylisting.txt" can be opened for reading. */
    
        if( (openfile = fopen("directorylisting1.txt", "rt")) == NULL)
        {
            perror("\ndirectorylisting1.txt");
            exit( EXIT_FAILURE );
        }
    
        /* Copy the lines in the file to the array */
    
        counter = 0;
    
        while((fgets(LineData[counter].stringstorage, LINELENGTH, openfile) != NULL) && (counter < NUMBEROFFILES))
        {
    		lastfilenumber = counter;
            counter++;
    		
        }
    
        fclose(openfile);
    
    	for( counter = 0; counter < lastfilenumber; counter++)
    	{
    		if( (comma = strchr( LineData[counter].stringstorage, ',')) != NULL )
    		{
    	sscanf(LineData[counter].stringstorage, "%d%/%d/%d %d:%d %s %d,%d %s",&LineData[counter].month, 
    &LineData[counter].day, &LineData[counter].year, 
    &LineData[counter].hour,&LineData[counter].minute,LineData[counter].string1,
    &LineData[counter].number1,&LineData[counter].number2, &LineData[counter].string2);
    		}
    
    		if( (comma = strchr( LineData[counter].stringstorage, ',')) == NULL )
    		{
    sscanf(LineData[counter].stringstorage, "%d%/%d/%d %d:%d %s %d,%d %s", &LineData[counter].month, 
    &LineData[counter].day, &LineData[counter].year, &LineData[counter].hour, &LineData[counter].minute,
    LineData[counter].string1, &LineData[counter].number1, &LineData[counter].string2);
    		}
    
    		for( counter = 0; counter < lastfilenumber; counter++) 
    		{
    			printf("Filename #%d: %s", counter, LineData[counter].string2);
    		}
    	}
    
        return 0;
    }
    My aim is to read a file containing:
    Code:
    12/16/2008  10:21 AM               969 bobthebuilder.html
    08/14/2008  06:13 AM            10,261 purplebarney.html
    08/14/2008  06:08 AM            12,083 mrpotatohead.html
    08/09/2008  05:10 PM             4,076 spongebob.html
    08/09/2008  05:41 PM             3,531 thewiggles.html
    12/06/2008  03:04 PM             1,016 lindsaylohan.html
    And to print out a list of filenames ending in .html only(LineData[counter].string2). I don't want to print out anything else in the line.

    Here is the output:

    Filename #0: лллллллллллллллллллллллллллллллллллллллл12/16/2008 10:21 AM 969 bobthebuilder.html
    Filename #1: лллллллллллллллллллллллллллллллллллллллл08/14/2008 06:13 AM 10,261 purplebarney.html
    Filename #2: лллллллллллллллллллллллллллллллллллллллл08/14/2008 06:08 AM 12,083 mrpotatohead.html
    Filename #3: лллллллллллллллллллллллллллллллллллллллл08/09/2008 05:10 PM 4,076 spongebob.html
    Filename #4: лллллллллллллллллллллллллллллллллллллллл08/09/2008 05:41 PM 3,531 thewiggles.html
    Filename #5: лллллллллллллллллллллллллллллллллллллллл12/06/2008 03:04 PM 1,016 lindsaylohan.html


    Why is it printing out the entire line, as well as some garbage?

    Thanks.
    Last edited by happyclown; 01-23-2009 at 04:21 AM. Reason: edited code to fit screen
    OS: Linux Mint 13(Maya) LTS 64 bit.

  9. #9
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Actually, I made a mistake in the loop for the situation if a string does not contain a comma. This is the corrected code:
    Code:
    if( (comma = strchr( LineData[counter].stringstorage, ',')) == NULL )
    		{
    	sscanf(LineData[counter].stringstorage, "%d%/%d/%d %d:%d %s %d %s", &LineData[counter].month,
    &LineData[counter].day,&LineData[counter].year,&LineData[counter].hour, &LineData[counter].minute,
    LineData[counter].string1,&LineData[counter].number1,
    &LineData[counter].string2);
    		}
    And the output is now:

    Filename #0: bobthebuilder.html
    Filename #1: лллллллллллллллллллллллллллллллллллллллл08/14/2008 06:13 AM 10,261 purplebarney.html

    Filename #2: лллллллллллллллллллллллллллллллллллллллл08/14/2008 06:08 AM 12,083 mrpotatohead.html

    Filename #3: лллллллллллллллллллллллллллллллллллллллл08/09/2008 05:10 PM 4,076 spongebob.html

    Filename #4: лллллллллллллллллллллллллллллллллллллллл08/09/2008 05:41 PM 3,531 thewiggles.html

    Filename #5: лллллллллллллллллллллллллллллллллллллллл12/06/2008 03:04 PM 1,016 lindsaylohan.html


    At least the first line works.
    Last edited by happyclown; 01-23-2009 at 04:15 AM. Reason: edited code to fit screen
    OS: Linux Mint 13(Maya) LTS 64 bit.

  10. #10
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Ok, I fixed it. The problem was that my I had the for loop to print the filenames within the for loop that used sscanf to break up the string.

    Here's the working code:
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    #define NUMBEROFFILES 1500
    #define LINELENGTH 150
    #define FILENAMELENGTH 40
    #define BEGINNINGOFHTMLLIST 5  /* First file in html list */
    
    int main( void )
    { 
        int lastfilenumber;
        FILE *openfile, *comma;
        int counter;
    
    	struct data {
            int month, day, year, hour, minute;
            char string1[2+1];
    		int number1, number2;
            char string2[FILENAMELENGTH];
            char stringstorage[LINELENGTH];  /* Used to store strings from file */
        } LineData[NUMBEROFFILES];
    
        /* Get a list of files in the directory "testwebsite", and redirect the
        output to a file called "directorylisting.txt". */
    
        // system("dir c:\\testwebsite\\*.html > directorylisting.txt");
    
        /* Test to see that the file "directorylisting.txt" can be opened for reading. */
    
        if( (openfile = fopen("directorylisting1.txt", "rt")) == NULL)
        {
            perror("\ndirectorylisting1.txt");
            exit( EXIT_FAILURE );
        }
    
        /* Copy the lines in the file to the array */
    
        counter = 0;
    
        while((fgets(LineData[counter].stringstorage, LINELENGTH, openfile) != NULL) && (counter < NUMBEROFFILES))
        {
    		lastfilenumber = counter;
            counter++;
    		
        }
    
        fclose(openfile);
    
    	for( counter = 0; counter < lastfilenumber; counter++)
    	{
    		if( (comma = strchr( LineData[counter].stringstorage, ',')) != NULL )
    		{		
    sscanf(LineData[counter].stringstorage, "%d%/%d/%d %d:%d %s %d,%d %s", &LineData[counter].month,
    &LineData[counter].day, &LineData[counter].year, &LineData[counter].hour,
    &LineData[counter].minute, LineData[counter].string1, &LineData[counter].number1,
    &LineData[counter].number2, &LineData[counter].string2);
    		}
    
    		if( (comma = strchr( LineData[counter].stringstorage, ',')) == NULL )
    		{
    	sscanf(LineData[counter].stringstorage, "%d%/%d/%d %d:%d %s %d %s", &LineData[counter].month,
    &LineData[counter].day, &LineData[counter].year, &LineData[counter].hour, &LineData[counter].minute,
    LineData[counter].string1, &LineData[counter].number1,&LineData[counter].string2);
    		}
    	}
    
    	for( counter = 0; counter < lastfilenumber; counter++) 
    	{	
    			printf("Filename #%d: %s\n", counter, LineData[counter].string2);
    	}
    
        return 0;
    }
    Here's the output:

    Filename #0: bobthebuilder.html
    Filename #1: purplebarney.html
    Filename #2: mrpotatohead.html
    Filename #3: spongebob.html
    Filename #4: thewiggles.html
    Filename #5: lindsaylohan.html


    MISSION ACCOMPLISHED!

    C is AWESOME!
    Last edited by happyclown; 01-23-2009 at 04:50 AM. Reason: edited code to fit screen
    OS: Linux Mint 13(Maya) LTS 64 bit.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If C is awesome, you should try C++
    It even more awesome, with things that will amaze you to your core
    But on a serious note, your indentation needs work.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 03-19-2009, 10:56 AM
  2. Strings Program
    By limergal in forum C++ Programming
    Replies: 4
    Last Post: 12-02-2006, 03:24 PM
  3. Programming using strings
    By jlu0418 in forum C++ Programming
    Replies: 5
    Last Post: 11-26-2006, 08:07 PM
  4. read certain strings from file
    By shatred in forum C++ Programming
    Replies: 2
    Last Post: 10-22-2006, 02:48 PM
  5. cin strings till eof
    By bfedorov11 in forum C++ Programming
    Replies: 2
    Last Post: 10-15-2003, 07:27 AM