Reading a string

This is a discussion on Reading a string within the C Programming forums, part of the General Programming Boards category; Hi, If getchar() reads the next character from stdin and getc() reads the next character from a file, which function ...

  1. #1
    Registered User
    Join Date
    Aug 2003
    Posts
    93

    Reading a string

    Hi,

    If getchar() reads the next character from stdin and getc() reads the next character from a file, which function can I use to read a character from a string ?


    tia,

  2. #2
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Can you give some sample code, trying to show what you're after?

    A string, when stored in memory, is simply an array. You don't need a function to access it, just array sub-scripting.

    myarray[5] will get you the 6th character.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  3. #3
    Registered User
    Join Date
    Aug 2003
    Posts
    93
    Sorry Hammer,

    The strings are going to be different lengths and the position I will be after will vary, what I have so far is

    Code:
    int process_record(char * current_record, FILE ** fp)
    {
    char buffer[BUFSIZ];
    char activity_month[BUFSIZ];
    char current_month[BUFSIZ];
    int start_date;
    int end_date;
    size_t index = 0;
    int ch, fields = 0;
    time_t curtime;
    struct tm *loctime;
    
       /* Get the current time. */
       curtime = time(NULL);
    
       /* Convert it to local time representation. */
       loctime = localtime(&curtime);
    
       /* get the current date in decimal format */
       strftime(current_month, BUFSIZ, "%Y%m", loctime);
    
       if(fp[IN_FILE] != NULL)
       {
          while(!strcmp(current_record, "\n"))
          {
             /* populate the temporary store */
             buffer[index] = '\0';
    
             if(strtok(current_record, ";"))
             {
                fields++;
    
                /* field 80 begins at the 79th separator */
                if(fields == 79 && *buffer == NULL)
                {
                   error_func("In get_activity_month().", "Error : Activity_Month has no data", SYS | FATAL);
                }
                else if(fields == 79)
                {
                   /* get the year and month from the file */
                   strncpy(activity_month, buffer, 6);
                   start_date = atoi(current_month);
                   start_date = start_date - 100;
                   end_date = atoi(current_month);
    
                   if(!strcmp(activity_month, current_month))
                   {
                      /* current month records only */
                      return 1;
                   }
                   else if(atoi(activity_month) > start_date && atoi(activity_month) < end_date)
                   {
                      /* previous twelve months - not including current month */
                      return 3;
                   }
                   else
                   {
                      /* everything else */
                      return 4;
                   }
                }
             }
          }
       }
       return 0;
    }

    I just want to be able to traverse along the string grabbing 6 chars at a specific point, which hopefully I have captured successfully


    tia,

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826

    Re: Reading a string

    Originally posted by darfader
    Hi,

    If getchar() reads the next character from stdin and getc() reads the next character from a file, which function can I use to read a character from a string ?


    tia,
    You don't use anything. You simply access it. Just to name a few:
    Code:
    char buf[BUFSIZ] = "this is your string";
    char foo;
    char *bar = buf;
    
    foo = buf[SOME_NUMBER];
    foo = *(buf + SOME_NUMBER);
    foo = *bar; /*then use bar to move down the string*/
    There are many ways to get whatever character you want from a string. If you're just moving six down at a time, do something like:

    bar += 6;

    Blah blah...

    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Aug 2003
    Posts
    93
    thanks Quzah



  6. #6
    Registered User
    Join Date
    Aug 2003
    Posts
    93
    sorry, still haven't got it

    Code:
    int process_record(char * current_record)
    {
    char buffer[BUFSIZ];
    char activity_month[BUFSIZ];
    char current_month[BUFSIZ];
    int start_date;
    int end_date;
    int ch, fields = 0, records = 0;
    time_t curtime;
    struct tm *loctime;
    char * record = current_record;
    int loop, count = 0;
    
       /* Get the current time. */
       curtime = time(NULL);
    
       /* Convert it to local time representation. */
       loctime = localtime(&curtime);
    
       /* get the current date in decimal format */
       strftime(current_month, BUFSIZ, "%Y%m", loctime);
    
       count = strlen(record);
    
          for(loop = 0; loop < record[count]; loop++)
          {
             if(buffer[loop] = (char)(strtok(record, ";")))
             {
                fields++;
    
                /* field 80 begins at the 79th separator */
                if(fields == 78 && *buffer == NULL)
                {
                   error_func("In get_activity_month().", "Error : Activity_Month has no data", SYS | FATAL);
                }
                else if(fields == 78)
                {
                   /* get the year and month from the file */
                   strncpy(activity_month, buffer, 6);
                   start_date = atoi(current_month);
                   start_date = start_date - 100;
                   end_date = atoi(current_month);
    
                   if(!strcmp(activity_month, current_month))
                   {
                      /* current month records only */
                      return 1;
                   }
                   else if(atoi(activity_month) > start_date && atoi(activity_month) < end_date)
                   {
                      /* previous twelve months - not including current month */
                      return 3;
                   }
                   else
                   {
                      /* everything else */
                      return 4;
                   }
                }
             }
          }
    
       return 0;
    }

    I am only getting one char instead of the six that I need


    tia,

  7. #7
    Registered User
    Join Date
    Dec 2001
    Posts
    34
    strtok returns a pointer to the next available token.

    Are you wanting to copy a pointer into buffer[loop]? Or are you wanting buffer to point to the location of that token?

    Edit:

    Also, if there is not a NULL character in the 6 that are strncpy'd, the atoi will *probably* fail. The variable names are different, is this correct?

    Code:
                   strncpy(activity_month, buffer, 6);
                   start_date = atoi(current_month);
    Last edited by clu82; 09-19-2003 at 10:46 AM.

  8. #8
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    Code:
    count = strlen(record);
    for(loop = 0; loop < record[count]; loop++)
    Since count is the length of the record, record[count] is the null terminator, which is zero. Did you mean to do this?
    Code:
    count = strlen(record);
    for(loop = 0; loop < count; loop++)
    -----
    Code:
    if(buffer[loop] = (char)(strtok(record, ";")))
    To me, this looks like an example of adding a cast to incorrect code in order to turn off a warning, while leaving the incorrect code in place to do bad things.

    [edit]
    Might it be easier to pick off the integer components of the date from the string using sscanf?
    Code:
    #include <stdio.h>
    
    int main(void)
    {
       const char text[] = "20030919";
       int year, month, day;
       if(sscanf(text, "%4d%2d%2d", &year, &month, &day) == 3)
       {
          printf("month = %d, day = %d, year = %d\n", month, day, year);
       }
       return 0;
    }
    
    /* my output
    month = 9, day = 19, year = 2003
    */
    [/edit]
    Last edited by Dave_Sinkula; 09-19-2003 at 10:49 AM.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  9. #9
    Registered User
    Join Date
    Aug 2003
    Posts
    93
    clu82:

    Are you wanting to copy a pointer into buffer[loop]? Or are you wanting buffer to point to the location of that token?
    no, that is probably my mistake, I wanted to establish the location of a particluar token [delimiter] and then copy everything after that. Then I would take only the first six characters from the string and use them, they being 200309 from a possible 20030922.00




    Dave_Sinkula:

    I have changed the loop and removed the bad assignment. Using sscanf() looks like a good idea and should be okay, once I find out why I am reading only the first field and not the 80th !


    thank you both for you help

  10. #10
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    I'll continue with the a modified version of the file.txt that I had posted previously.
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    
    int main(void)
    {
       time_t now = time(NULL);
       struct tm *info = localtime(&now);
       const char filename[] = "file.txt";
       FILE *file = fopen(filename, "r");
       fputs(ctime(&now), stdout);
       if ( file != NULL )
       {
          char buffer [ 1024 ];
          while ( fgets(buffer, sizeof buffer, file) != NULL )
          {
             size_t i = 0;
             char *token = strtok(buffer, ";");
             while ( token != NULL )
             {
                if ( ++i == 80 )
                {
                   break;
                }
                token = strtok(NULL, ";");
             }
             if ( token != NULL )
             {
                int year, month, day;
                if ( sscanf(token, "%4d%2d%2d", &year, &month, &day) == 3 )
                {
                   printf("token = \"%s\": month = %d, day = %d, year = %d",
                          token, month, day, year);
                   if ( year  == info->tm_year + 1900 &&
                        month == info->tm_mon + 1     &&
                        day   == info->tm_mday )
                   {
                      fputs(" <---", stdout);
                   }
                   putchar('\n');
                }
             }
          }
          fclose(file);
       }
       return 0;
    }
    
    /* my output
    Mon Sep 22 10:11:53 2003
    token = "20030920": month = 9, day = 20, year = 2003
    token = "20030921.00": month = 9, day = 21, year = 2003
    token = "20030922.00": month = 9, day = 22, year = 2003 <---
    token = "20030923": month = 9, day = 23, year = 2003
    token = "20030924": month = 9, day = 24, year = 2003
    */
    Attached Files Attached Files
    Last edited by Dave_Sinkula; 09-22-2003 at 10:25 AM.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  11. #11
    Registered User
    Join Date
    Aug 2003
    Posts
    93
    thanks Dave,

    I have tried this before
    Code:
                   while(buffer != NULL)
                   {
                      buffer = strtok(NULL, ";");
                   }
    but sending NULL to strtok() made the program core dump


    I can see that yours works fine, but cannot explain what else I was doing wrong with mine earlier,

    cheers



    ps:

    I have used your program on my original files too and no problems

  12. #12
    twm
    twm is offline
    root
    Join Date
    Sep 2003
    Posts
    232
    >but sending NULL to strtok() made the program core dump
    You always have to call strtok with a valid modifiable string the first time. For subsequent tokens in the string, you pass NULL as the first argument so that strtok knows to work on the same string from last time. That's most likely the root of your problem.
    The information given in this message is known to work on FreeBSD 4.8 STABLE.
    *The above statement is false if I was too lazy to test it.*
    Please take note that I am not a technical writer, nor do I care to become one.
    If someone finds a mistake, gleaming error or typo, do me a favor...bite me.
    Don't assume that I'm ever entirely serious or entirely joking.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Please check my C++
    By csonx_p in forum C++ Programming
    Replies: 263
    Last Post: 07-24-2008, 10:20 AM
  2. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  3. IRC, reading the stream
    By Iyouboushi in forum C# Programming
    Replies: 6
    Last Post: 08-03-2006, 06:34 PM
  4. Program using classes - keeps crashing
    By webren in forum C++ Programming
    Replies: 4
    Last Post: 09-16-2005, 04:58 PM
  5. problems with overloaded '+' again
    By Brain Cell in forum C++ Programming
    Replies: 9
    Last Post: 04-14-2005, 06:13 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21