I am trying to make a translator.
This is the part where I put all the strings from the text file on the memory.
But the program ignores the first string of the text file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct b
{
char b[30];
}b;
int main()
{
int d,c,i=0;
char k[30],x;
b *a;
FILE *fp;
if ((fp=fopen("translate.txt","r"))==NULL)
{
printf("Σφάλμα κατά το άνοιγμα του αρχείου\n");
}
else
{
while(!feof(fp))
{
fscanf(fp,"%s",k);
i++;
}
a=malloc((i)*(sizeof(b)));
fclose(fp);
}
if ((fp=fopen("translate.txt","r+"))==NULL)
{
printf("Σφάλμα κατά το άνοιγμα του αρχείου\n");
}
else
{
rewind(fp);
for (c=0;c<i;c++)
{
fscanf(fp,"%s",a[c].b);
}
fclose(fp);
}
1. You should write this loop (so as to check return of fscanf ) —
for (c=0;c<i;c++)
{
fscanf(fp,"%s",a[c].b);
}
as —
c=0;
while (fscanf(fp,"%29s",a[c].b) == 1 && c<i){
...
c++;
}
2. Also while(!feof(fp)) is wrong, so instead use fscanf to control the loop —
while (fscanf(fp,"%29s",k)==1)
i++;
Note — And, just to avoid confusion, give different names to your structure member and structure.
after applying all the comments, the resulting code is:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main( void )
{
char **lines = NULL;
size_t lineCount = 0;
FILE *fp = NULL;
if ((fp=fopen("translate.txt","r"))==NULL)
{
perror("Σφάλμα κατά το άνοιγμα του αρχείου\n");
exit( EXIT_FAILURE );
}
char * inputBuf = NULL;
size_t inputLen = 0;
while( getline( &inputBuf, &inputLen, fp ) )
{
lineCount++;
char **tempLines = realloc( lines, (lineCount+1)*sizeof( char*) );
if( !tempLines )
{ // then realloc failed
perror( "realloc failed");
free( lines );
exit( EXIT_FAILURE );
}
lines = tempLines;
lines[lineCount] = strdup( inputBuf );
lineCount++;
}
fclose(fp);
free( lines );
return 0;
} // end function: main
however, this code is not very efficient as it repeatedly calls realloc()
To fix that, initially allocate enough room in lines[] for several lines, say 10, then keep a count of how many of those pointers are being used.
When all the allocated pointers are used and need to add another line, then double the allocation via realloc().
Related
I am attempting to get my program to read strings from another file, parse them for certain keywords, and then add to a counting variable whenever they appear in the other file. However, I can't seem to get anything but the number of lines to count. What could I be doing wrong here?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// check that fp is not null omitted but needed
const char getLine[1] = "";
const char getFor[4] = "for";
char line[500];
int lineCount = 0;
int forCount = 0;
int x = 0;
int main() {
FILE* fp = fopen("file.txt", "r");
if (fp == NULL) {
perror("Error opening file");
return(-1);
}
while (fgets(line, 499, fp) != NULL) {
strstr(line, getLine);
lineCount++; //Essentially counting the number of lines in file.
}
printf("Line count is %d.\n", lineCount);
memset(line, 0, sizeof(line)); //Resetting the memory of line.
while (fgets(line, 499, fp) != NULL) {
char *findFor;
findFor = strstr(line, getFor);
if (findFor != NULL) { //Attempting to count each time an instant of 'for' appears.
forCount++;
}
}
printf("For count is %d.\n", forCount);
fclose(fp);
}
The code is reading through the whole file to count the lines, but then trying to read through it again (without a rewind() / fseek()). So on the second loop the file is at end-of-file.
It's not necessary to count the lines, and the "for"s in two separate loops, just do it in one.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// check that fp is not null omitted but needed
const char getFor[4] = "for";
char line[500];
int lineCount = 0;
int forCount = 0;
int main( )
{
FILE *fp = fopen( "file.txt", "r" );
if ( fp == NULL )
{
perror( "Error opening file" );
return ( -1 );
}
while ( fgets( line, sizeof( line ), fp ) != NULL )
{
char *findFor;
findFor = strstr( line, getFor );
if ( findFor != NULL )
{
// Attempting to count each time an instance of 'for' appears.
forCount++;
}
lineCount++;
}
printf( "Line count is %d.\n", lineCount );
printf( "For count is %d.\n", forCount );
fclose( fp );
return 0;
}
Also you're not counting the number of "for"s in the file, you're counting the number of lines with "for" in them. If a line has multiples, it's just counted as one.
I have a file with 3 lines in it, I'm tring to read this file and save each line as a separate string.
here is what I tried to do, it does save the first line but it overrides it by saving the first line and the second line' and I can't get my head around on how to do save each line as an individual string , and also I'm getting an error->
* stack smashing detected *: /home/ubuntu/workspace/ex12.c.o terminated
Aborted
#include <stdio.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include<stdio.h>
#include<fcntl.h>
#include<errno.h>
#include <unistd.h>
extern int errno;
int main( int argc, char *argv[] ) {
char *path1;
char firstline[80];
char secondline[80];
char thirdline[80];
printf("Program name %s\n", argv[0]);
if( argc == 2 ) {
printf("The path of the config file that you supplied is %s\n", argv[1]);
}
else if( argc > 2 ) {
printf("Too many arguments supplied.\n");
}
else {
printf("One argument expected.\n");
}
int fd1 = open(argv[1], O_RDONLY | O_CREAT);
if (fd1 ==-1)
{
// print which type of error have in a code
printf("Error Number % d\n", errno);
// print program detail "Success or failure"
perror("Program");
exit(EXIT_FAILURE);
}
else {
char c;
int i=0;
while ((read(fd1, &c, 1) == 1) )
{
firstline[i++]=c;
if(c=='\n')
{
//printf("end of line");
printf("%s",firstline);
}
}
}
int close(int fd1);
return 0;
}
NOTE: I DO NOT WANT to use fopen,fgets,sscanf or getline.
Any help would be appreciated
Here is an example to demonstrate the brake from first loop from your example:
#define MAXLENGTH 80
...
char firstline[MAXLENGTH + 1] = {0};
char secondline[MAXLENGTH + 1] = {0};
char thirdline[MAXLENGTH + 1] = {0};
....
else {
char c;
int i=0;
while ((read(fd1, &c, 1) == 1 && i < MAXLENGTH)
{
firstline[i++]=c;
if(c=='\n')
{
break; /* break from first loop */
}
}
/* add a '\0' to the end of the string! */
firstline[i] = '\0';
//printf("end of line");
printf("%s",firstline);
i=0;
while ((read(fd1, &c, 1) == 1 && i < MAXLENGTH)
{
secondline[i++]=c;
if(c=='\n')
{
break; /* break from second loop */
}
}
/* add a '\0' to the end of the string! */
secondline[i] = '\0';
printf("%s",secondline);
i = 0;
int i=0;
while ((read(fd1, &c, 1) == 1 && i < MAXLENGTH)
{
thirdline[i++]=c;
if(c=='\n')
{
break; /* break from third loop */
}
}
/* add a '\0' to the end of the string! */
thirdline[i] = '\0';
//printf("end of line");
printf("%s",thirdline);
}
...
printf prints until a NULL terminating character is seen. Your printf goes over unallocated memory areas because you are not inserting a NULL(value 0) at the end of the string.
Also, you forgot to reinitialize i to 0.
while ((read(fd1, &c, 1) == 1) )
{
firstline[i++]=c;
if(c=='\n')
{
firstline[i] = 0;
i = 0;
//printf("end of line");
printf("%s",firstline);
}
}
The reason you are getting the error is most likely because you never reset i back to 0 so you keep reading more than 80 characters in to firstline
As to saving each line in to its own string, your just need to use you other variables, instead of using firstline all the time.
There a couple of ways to do that:
When you detect end of line exit the loop (with break), and start another loop where you will put the characters in secondline. Do the same for third.
If you already learned a bit about pointers, you can keep one loop, but use an extra variable, like char *currentLine that will hold the address of the array you want to read in to. Change the address every time you detect end of line like this: currentLine = secondline.
Also remember to put '\0' at the end of every line you read, or your program may print garbage when you try to print what you read to the screen.
the following proposed code:
cleanly compiles
performs the desired functionality
proper checks for and handles errors
gives 'magic' numbers (3, 80) meaningful names
and now, the proposed code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#define MAX_LINES 3
#define MAX_LINE_LEN 80
int main( int argc, char *argv[] )
{
char Lines[ MAX_LINES ][ MAX_LINE_LEN ] = { '\0' };
if( argc != 2 )
{
fprintf( stderr, "USAGE: %s <configFileName>\n", argv[0] );
exit( EXIT_FAILURE );
}
// implied else, correct number of command line arguments
int fd1 = open(argv[1], O_RDONLY );
if (fd1 ==-1)
{
perror( "open failed" );
exit(EXIT_FAILURE);
}
// implied else, open successful
char c;
for( int i = 0; i < MAX_LINES; i++ )
{
for( int j=0; j< MAX_LINE_LEN; j++ )
{
ssize_t bytecount = read(fd1, &c, 1 );
if( bytecount < 0 )
{
perror( "read failed" );
close( fd1 );
exit( EXIT_FAILURE );
}
// implied else, read successful
Lines[ i ][ j ] = c;
if( c == '\n' )
{
break;
}
}
}
for( int i = 0; i< MAX_LINES; i++ )
{
printf( "%s\n", Lines[i] );
}
close( fd1 );
return 0;
}
Note: this code assumes that each line is less than 80 characters
running the proposed code against its' own source file results in:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
Understanding handling direct pointers in C
Here is a code that works for an array of strings for fixed number of items and fixed line length :
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXNAMELEN 100
#define MAXLINELEN 100
#define MAXITEMS 1000
int main(int argc, char ** argv) {
FILE * infile, * outfile;
char name[MAXNAMELEN];
char line[MAXLINELEN];
char lines[MAXITEMS][MAXLINELEN];
int i, items = 0;
printf("Enter a source filename: ");
fgets(name, sizeof(name), stdin);
name[strlen(name)-1] = '\0'; // strip newline
infile = fopen(name, "r");
while (fgets(line, sizeof(line), infile)) {
strcpy(lines[items], line);
items++;
}
qsort(lines, items, MAXLINELEN, strcmp);
printf("Enter a destination filename: ");
fgets(name, sizeof(name), stdin);
name[strlen(name)-1] = '\0'; // strip newline
outfile = fopen(name, "w");
for (i=0; i<items; i++) {
fputs(lines[i], outfile);
}
fclose(infile);
fclose(outfile);
}
Problem description and code
If I try to read an input.txt file that is within MAXLINELEN and MAXITEMS, the program works fine. Now imagine I am reading from a much larger "inputfile" line by line where maximum line length could be anything, then I would have to use a character pointer (char*) to read the input. char* linesptr[MAXITEMS];
Here is my code where I am trying to accomplish reading from an input file line by line delimited by a newline character.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#define MAXNAMELEN 1000
#define MAXLINELEN 1000
#define MAXITEMS 100000
char* linesptr[MAXITEMS];
int
main(int argc, char ** argv) {
FILE * infile, * outfile;
char name[MAXNAMELEN];
char line[MAXLINELEN];
int i, items = 0;
printf("Enter a source filename: ");
fgets(name, MAXNAMELEN, stdin);
name[strlen(name)-1] = '\0'; // strip newline
printf("%s infile \n",name);
infile = fopen(name, "r");
while (fgets(line, MAXLINELEN, infile)) {
int length = strlen(line);
line[length-1] = '\0';
linesptr[items] = line; *<- I am writing to the same mem location*
printf("the input string %d is : %s \n",items, linesptr[items]);
items++;
}
qsort(linesptr, items, MAXLINELEN, strcmp);
printf("Enter a destination filename: ");
fgets(name, sizeof(name), stdin);
name[strlen(name)-1] = '\0'; // strip newline
outfile = fopen(name, "w");
for (i=0; i<items; i++) {
fputs(linesptr[i], outfile);
}
fclose(infile);
fclose(outfile);
}
PROBLEM
I am copying the pointer address into the nth cell of the array linesptr where nth is the value=items (Here is the reference line from the code: linesptr[items] = line;). so when you print the final answer, I am referencing the same memory address to the buffer named line, the memory location at line will always point to the most recent fgets(). I understand the error but I do not know how to fix the issue. I would appreciate any help to fix the bug in the code.
Copy the line to a dynamically-allocated string.
while (fgets(line, MAXLINELEN, infile)) {
int length = strlen(line);
if (length > 0 && line[length-1] == '\n') {
line[length-1] = '\0';
length--;
}
char *linecopy = malloc(length+1);
strcpy(linecpy, line);
linesptr[items] = linecpy;
printf("the input string %d is : %s \n",items, linesptr[items]);
items++;
}
And if you want to handle more than MAXITEMS lines, you should allocate linesptr using malloc() as well. When you get to the current size of linesptr you can use realloc() to make it longer. See Read unknown number of lines from stdin, C for detailed code.
See How to qsort an array of pointers to char in C? for the proper way to sort an array of pointers to strings.
You ask for a example, so here it is:
the following proposed code:
is written for readability
checks for and handles error conditions
makes use of getline() and realloc()
is not as efficient as it could be because it calls realloc() for every line in the source file.
properly/safely uses strcspn() for removing any (possible) trailing newline characters
could have simplified the code by extracting the 'cleanup' to a sub function rather than repeating the same 'cleanup' code when ever an error was encountered.
used size_t rather than int for indexes into arrays to avoid implicit conversions
minimized the scope of variables where possible
passes proper third parameter to qsort()
properly implements the compare() helper function for qsort()
and now, the proposed code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXNAMELEN 1024
// prototypes
int compare(const void *, const void *);
int main( void )
{
printf("Enter a source filename: ");
char name[ MAXNAMELEN ];
if( !fgets(name, sizeof( name ), stdin) )
{
perror( "fgets for input file name failed" );
exit( EXIT_FAILURE );
}
// implied else, fgets for input file name successful
name[strcspn( name, "\n" ) ] = '\0'; // strip newline
printf("%s infile \n",name);
FILE *fp_in = fopen(name, "r");
if( !fp_in )
{
perror( "fopen for input file failed" );
exit( EXIT_FAILURE );
}
// implied else, fopen for input file successful
char **linesarray = NULL;
size_t numLines = 0;
char *line = NULL;
size_t lineLen = 0;
while( getline( &line, &lineLen, fp_in ) != -1 )
{
char ** temp = realloc( linesarray, (numLines+1) * sizeof( char* ) );
if( !temp )
{
perror( "realloc failed" );
fclose( fp_in );
for( size_t i = 0; i< numLines; i++ )
{
free( linesarray[i]);
}
free( linesarray );
exit( EXIT_FAILURE );
}
// implied else, realloc successful
linesarray = temp;
linesarray[ numLines ] = line;
numLines++;
// prep for next iteration
line = NULL;
lineLen = 0;
}
free( line );
fclose( fp_in );
//puts( "all file read in" );
qsort( linesarray, numLines, sizeof( char * ), compare );
//puts( "file sorted" );
printf("Enter a destination filename: ");
if( !fgets(name, sizeof(name), stdin) )
{
perror( "fgets for output file name failed" );
for( size_t i = 0; i< numLines; i++ )
{
free( linesarray[i]);
}
free( linesarray );
exit( EXIT_FAILURE );
}
// implied else, fgets() for output file name successful
name[strcspn( name, "\n" ) ] = '\0'; // strip newline
FILE *fp_out = fopen(name, "w");
if( !fp_out )
{
perror( "fopen for output file failed" );
for( size_t i = 0; i< numLines; i++ )
{
free( linesarray[i]);
}
free( linesarray );
exit( EXIT_FAILURE );
}
// implied else, fopen for output file successful
for (size_t i=0; i<numLines; i++)
{
if( fputs(linesarray[i], fp_out ) == EOF )
{
perror( "fputs failed" );
fclose( fp_out );
for( size_t i = 0; i< numLines; i++ )
{
free( linesarray[i]);
}
free( linesarray );
exit( EXIT_FAILURE );
}
}
fclose( fp_out );
for( size_t i = 0; i< numLines; i++ )
{
free( linesarray[i]);
}
free( linesarray );
}
int compare(const void *ls, const void *rs )
{
char *leftSide = *(char**)ls;
char *rightSide = *(char**)rs;
return strcmp( leftSide, rightSide );
}
Here is the complete working solution to read in a file (big data), sort it and write it to a file:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#define MAXNAMELEN 1000
#define MAXLINELEN 5000
#define MAXITEMS 100000
char* linesptr[MAXITEMS];
int compare_function(const void *name1, const void *name2)
{
const char *name1_ = *(const char **)name1;
const char *name2_ = *(const char **)name2;
return strcmp(name1_, name2_);
}
int
main(int argc, char ** argv)
{
FILE * infile, * outfile;
char name[MAXNAMELEN];
char line[MAXLINELEN];
int i, items = 0;
printf("Enter a source filename: ");
fgets(name, MAXNAMELEN, stdin);
name[strlen(name)-1] = '\0'; // strip newline
infile = fopen(name, "r");
while (fgets(line, MAXLINELEN, infile)) {
int length = strlen(line);
line[length-1] = '\0';
char *linecopy = malloc(length);
strcpy(linecopy, line);
linesptr[items] = linecopy;
items++;
}
qsort(linesptr, items, sizeof(char *), compare_function);
printf("Enter a destination filename: ");
fgets(name, sizeof(name), stdin);
name[strlen(name)-1] = '\0'; // strip newline
outfile = fopen(name, "w");
for (i=0; i<items; i++) {
fprintf(outfile, "%s\n", linesptr[i]);
}
fclose(infile);
fclose(outfile);
}
i have a problem with my c program,
it should read words/strings from txt file, then count length of them.
when i run my program, it doesnt response
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *f;
char c;
char word[50];
int a,b=0;
if ((f = fopen("file.txt", "r")) == NULL)
{
printf("CANT OPEN THE FILE" "\n");
return 1;
}
while((c=fgetc(f))!=EOF){
if (c==' ')b++;
word[b]=word[b]+c;
}
for (a=0;a<b;a++){
printf("%c ",word[0]);
}
return 0;
}
it should do this: first i open my file, then i will read every char from this file+storing this chars in array word, then when blank space occurs(' '), it should write chars to next index of array, so the words will be created on different indexes of array
then it should count the lenght of words, but that should be easy to implement, thx a sorry for my english
They are ALOT of errors with the code you shared :
J is not declared, so you need to add int j = 0; I'm assuming than j is the number on whitespace on your doc.
word[b]=word[b]+c; get changed into word[b]= c;
You add an incremntation on b in your loop then, so you wont write only on word[0].
Your printing is bad aswell, you would only show the first letter over and over.
This is the final code, corrected. It shows the entire file if the file is less than 200 caracters. J is the number of whitespace.
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *f;
char c;
char word[200];
int a,b=0;
int j = 0;
if ((f = fopen("file.txt", "r")) == NULL)
{
printf("CANT OPEN THE FILE" "\n");
return 1;
}
while((c=fgetc(f))!=EOF){
if (c==' ')j++;
word[b]= c;
b++;
}
for (a=0;a<b;a++){
printf("%c",word[a]);
printf("The file contains %d caracters, and %d whitespaces", b, j);
}
return 0;
}
By the way, next time. try to compile at least. It's clear that you put no effort into it before submitting a question here on SO.
the following compiles and meets your description of what needs to be done
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // memset
#define MAX_WORD_LENGTH (50)
struct wordStruct_t
{
char word[MAX_WORD_LENGTH];
};
int main()
{
FILE *fp;
int c;
char word[50]; // assume max word length is < 50
int i = 0; // word byte index
int wordCount = 0; // count of words read
struct wordStruct_t * wordArray = NULL;
char * testArray = NULL;
if ((fp = fopen("file.txt", "r")) == NULL)
{
perror( "fopen failed for read of file.txt");
exit( EXIT_FAILURE );
}
// implied else open successful
memset( word, 0x00, sizeof( word ) );
while((c=fgetc(fp))!=EOF)
{
if( (c!=' ') && (c != '\n') )
{ // then letter to add to current word (should also check for word overflow)
word[i++] = c;
}
else
{ // else, end of word found
// allocate max room for new word
if( NULL == (testArray = realloc( wordArray, sizeof(struct wordStruct_t) * (wordCount+1)) ) )
{
perror( "realloc failed");
free( wordArray );
fclose( fp );
exit( EXIT_FAILURE );
}
// implied else, realloc successful
wordArray = (struct wordStruct_t*)testArray;
strcpy( wordArray[wordCount].word, word );
memset( word, 0x00, sizeof(word) ); // prep for next word
} // end if
} // end while
for (i = 0; i< wordCount; i++)
{
printf("word: %d is %s and contains %d bytes\n",
i,
wordArray[i].word,
(int)strlen(wordArray[i].word ) );
}
free( wordArray );
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //for string functions
int main()
{
FILE *f;
int c; //c should be an int
char word[50];
char *ptr; //to store each word
int a,b=0;
if ((f = fopen("file.txt", "r")) == NULL)
{
printf("CANT OPEN THE FILE" "\n");
return 1;
}
while((c=fgetc(f))!=EOF){
word[b++]=c;
}
for (a=0;a<b;a++){
printf("%c ",word[a]); //word[a] not word[0]
}
ptr=strtok(word," ");//get first word
a=0;
while(ptr!=NULL)
{
printf("Word %d which is %s is %d letters long",++a,ptr,strlen(ptr));
ptr=strtok(NULL," "); //get next word
}
return 0;
}
I am new to C and i am trying to iteratively call line in stream and check to see if it contains my search string or if it is null. I cant figure out how to make this check, i get a warning saying [Warning] comparison between pointer and integer or [Warning] assignment makes pointer from integer without a cast whenever i try and do this. can anyone help? thanks.
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
FILE *fpntr;
char *file_pathname, *first_line;
if (argc != 2) {
fprintf(stderr, "usage: %s FILE\n", argv[0]);
return EXIT_FAILURE;
}
file_pathname = argv[1];
if ((fpntr = fopen(file_pathname, "r")) == NULL ) {
fprintf(stderr, "Error opening file %s: %s\n", file_pathname, strerror(errno));
return EXIT_FAILURE;
} else {
grep_stream();
fclose(fpntr);
}
return EXIT_SUCCESS;
}
int grep_stream(FILE *fpntr, char *string, char *file_pathname) {
//warning is on next line
while ((? = get_next_line(fpntr)) == NULL ) {
perror("Error reading line");
exit(EXIT_FAILURE);
}
elseif()
{
printf("First line in : %s \n %s", file_pathname, string);
}
}
char *get_next_line(FILE *fpntr) {
char *buff = malloc(101);
int pos = 0;
int next;
while ((next = fgetc(fpntr)) != '\n' && next != EOF) {
buff[pos++] = next;
}
buff[pos] = '\0';
if (buff != NULL ) {
return buff;
} else
return NULL ;
}
Remember that C code is compiled top-to-bottom. The function get_next_line isn't declared by the time the while line is read.
Either move get_next_line's definition to before main's, or forward-declare it by saying:
char *get_next_line(FILE *fpntr);
beforehand. The reason that you're getting a warning instead of an error is that undeclared functions are assumed to return int and no assumptions are made about their parameters. That is, they have the type int().
Also, properly format your code for both your sake and of those who will be answering your questions (or working with you.)
add a * to the pointer of integer to convert it from pointer to integer
... i am trying to iteratively call line in stream...
Why not use fgets()?
Secondly, to match a substring in a string, you can use strstr()
Please use standard C library instead of re-inventing the wheel. It saves the day usually.
#include <assert.h> // I'm too dumb to program without assertions!
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
//#include <unistd.h> I prefer stdlib.h, couldn't see any need for non-portable header...
#define MAX_LINE (101) // define funky constants in one place for easy changing later.
// declare functions before using them
void grep_stream(FILE *fpntr, char *file_pathname);
char *get_next_line(FILE *fpntr);
int main(int argc, char *argv[]) {
FILE *fpntr;
char *file_pathname;
if (argc != 2) {
fprintf(stderr, "usage: %s FILE\n", argv[0]);
return EXIT_FAILURE;
}
file_pathname = argv[1];
if ((fpntr = fopen(file_pathname, "r")) == NULL ) {
fprintf(stderr, "Error opening file %s: %s\n", file_pathname, strerror(errno));
return EXIT_FAILURE;
}
else {
grep_stream(fpntr, file_pathname);
fclose(fpntr);
}
return EXIT_SUCCESS;
}
void grep_stream(FILE *fpntr, char *file_pathname) {
char* line;
int got_first = 0;
assert(fpntr);
assert(file_pathname); // I worry the guy who wrote main() might be an idiot like me!
//warning is on next line [not anymore!]
while ((line = get_next_line(fpntr)) != NULL ) {
if(!got_first) {
printf("First line in : %s \n%s\n", file_pathname, line);
got_first = 1;
}
// if we're not going to use it, let's not leak memory
free(line);
}
}
char *get_next_line(FILE *fpntr) {
char *buff = malloc(MAX_LINE);
int pos = 0;
int next;
assert(buff != NULL); // wouldn't it be nice to know malloc() worked?
while ((next = fgetc(fpntr)) != '\n' && next != EOF) {
buff[pos++] = (char)next;
assert(pos < (MAX_LINE-1)); // don't want to be right back on SO with a seg fault, eh?
}
buff[pos] = '\0';
if(next == EOF) {
free(buff);
buff = NULL;
}
return buff;
}