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,
Printable View
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,
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.
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,
You don't use anything. You simply access it. Just to name a few:Quote:
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,
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: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*/
bar += 6;
Blah blah...
Quzah.
thanks Quzah
:D
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,
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);
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 < record[count]; loop++)
-----Code:count = strlen(record);
for(loop = 0; loop < count; loop++)
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.Code:if(buffer[loop] = (char)(strtok(record, ";")))
[edit]
Might it be easier to pick off the integer components of the date from the string using sscanf?[/edit]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
*/
clu82:
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.00Quote:
Are you wanting to copy a pointer into buffer[loop]? Or are you wanting buffer to point to the location of that token?
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
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
*/
thanks Dave,
I have tried this before
but sending NULL to strtok() made the program core dump :(Code:while(buffer != NULL)
{
buffer = strtok(NULL, ";");
}
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 :)
>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.