Hi,

I have two issues that I am hoping to get assistance with.

To begin with, the code snippee below is designed to read a line from a file, then place a subset of the line in another array.

This works correctly when I place a number in arg 2 of strncpy (i.e. rec+10), but when I use the variable as shown (i.e. rec+namePosition) I receive the following error when compiling, "warning: passing argument 2 of ‘strncpy’ makes pointer from integer without a cast"

In addition, I am printing the name array for debugging purposes, and i am getting two of every line (i.e. when it works by adding rec+10 instead of the variable name)

The variable namePosition is an argument that is passed in via the commad line, and is set as follows
int namePosition = atoi(argv[3]); /* get the name position */

while(fgets(rec, recLength, file)!=NULL) {

               /* Add the null char to the end of the  name array */
               name[nameLength - 1] = '\0';

                /* place the name from the file in the name array */
               strncpy(name, rec+namePosition, nameLength -1);
               printf("%s \n", rec);
            }

Your use of 'name' and 'rec' seems completely screwed up.

Post your actual code, not some snippet you typed from memory.

Hi, thank you for looking. That is the actual code, but here is all of it.
I thought that I could get away with just showing the pertinent piece which works if I with an actual integer but not with an integer variable.

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

int main( int argc, char *argv[]) {

   if ( argc != 5 ) { /* argc should be 5 for correct execution */
      printf( "usage: %s fileName recLength namePosition nameLength \n", argv[0] );
   }
   else {

      int recLength = atoi(argv[2]);     /* get the record length */
      int namePosition = atoi(argv[3]);  /* get the name position */
      int nameLength = atoi(argv[4]);    /* get the length of the name field */
      int recArrayLength = recLength +1; /* add one to the record length for fgets */
      char rec[recArrayLength];          /* array for fgets function */
      nameLength = nameLength + 1;       /* create the length plus null char */
      char name[nameLength];             /* craeate the array to hold the name */

      FILE *file;  /* declare a FILE pointer

      /* open a text file for reading */
      file = fopen(argv[1], "r+");

      if(file==NULL) {
         printf("Error: can't open file.\n");
         fclose(file); /* DON'T PASS A NULL POINTER TO fclose !! */
         return 1;
      }
      else {
         printf("File opened successfully. nameLength %d \n", nameLength);

         /* keep looping until NULL pointer... */

         while(fgets(rec, recLength, file)!=NULL) {

               /* Add the null char to the end of the  name array */
               name[nameLength - 1] = '\0';

                /* place the name from the file in the name array */
               strncpy(name, rec+namePosition, nameLength -1);
               printf("%s \n", rec);
            }

       }

         printf("\n\nNow closing file...\n");
         fclose(file);
         return 0;
      }
  }

Well strictly speaking, that isn't C code to begin with.

$ gcc prog.c

$ gcc -ansi -pedantic -Wall -O2 prog.c
prog.c: In function ‘main’:
prog.c:16: warning: ISO C90 forbids variable-size array ‘rec’
prog.c:18: warning: ISO C90 forbids variable-size array ‘name’
prog.c:18: warning: ISO C90 forbids mixed declarations and code
prog.c:22:7: warning: "/*" within comment
prog.c:51: warning: control reaches end of non-void function

gcc by default is happy to compile it, but in strict mode, there are a number of problems.

Perhaps your compiler is barfing on your non-standard code.

Further problems are
> name[nameLength - 1] = '\0';
You read into rec, so why are you setting name?

If you were trying to remove the \n, then it's wrong for two reasons.
The other being that if the buffer is say 50 chars long, and you only type in 10, then the \n is nowhere near the end of the buffer.

> fclose(file); /* DON'T PASS A NULL POINTER TO fclose !! */
Excellent comment, but why is it still there?

Thank you for the reply, but it appears to sidestep the issues.

Can you help with the strncpy function?

I can move to a solaris box to resolve the new issues that you mentioned, but I happen to be currently writing on a debian box.


This code works --

strncpy (dest, from+10, length)

wherein I am stating that I want to copy everything in the 'from' array starting at the 10th byte, for the length stated, to the 'dest' array.

The problem is that when an integer variable is used, instead of an actual number i.e.

strncpy(dest, from+intVar, length)]

I get the following error,
"warning: passing argument 2 of ‘strncpy’ makes pointer from integer without a cast"

For what it is worth I solved this.

Adding the -std=c99 to the compile command allows variable length arrays.

Also, I set a pointer to the rec array and I was able to add the length as a variable.

If the file is like this in each record u have a namefield and u want to find out name from each record.
here is your modified code. comments are marked.

file sample:
-----------
John smith 23 bbsr
John smith 23 bbsr
John casio 23 bbsr
linga mary 21 wasington

you wanna extract names only then:
use record starting postion as "0 and length as you needed here 10"

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

int main( int argc, char *argv[]) {

   if ( argc != 5 ) { /* argc should be 5 for correct execution */
      printf( "usage: %s fileName recLength namePosition nameLength \n", argv[0] );
   }
   else {

      int recLength = atoi(argv[2]);     /* get the record length */
      int namePosition = atoi(argv[3]);  /* get the name position */
      int nameLength = atoi(argv[4]);    /* get the length of the name field */
      int recArrayLength = recLength +1; /* add one to the record length for fgets */
      char rec[recArrayLength];          /* array for fgets function */
      nameLength = nameLength + 1;       /* create the length plus null char */
      char name[nameLength];             /* craeate the array to hold the name */

      FILE *file;  /* declare a FILE pointer*/

      /* open a text file for reading */
      file = fopen(argv[1], "r+");

      if(file==NULL) {
         printf("Error: can't open file.\n");
         fclose(file); /* DON'T PASS A NULL POINTER TO fclose !! */
         return 1; //as u have return in if clause itself so no need to attach an else with it. so it removed
      }


         printf("nameLength %d rec_len:%d name_pos:%d\n", nameLength,recLength,namePosition);

         /* keep looping until NULL pointer... */

         while(fgets(rec, recLength, file)!=NULL) {

               /* Add the null char to the end of the  name array */
               //name[nameLength - 1] = '\0';   //no need of this line
				rec[strlen(rec)]='\0';			//it generally ends with '\n' need to replaced by '\0'

                /* place the name from the file in the name array */
               strncpy(name, rec+namePosition, nameLength -1);
			   name[nameLength - 1] = '\0';   //this this needed here
                
				printf("%s \n", name);  //name should be printed in stead of record
            }



         printf("\n\nNow closing file...\n");
         fclose(file);
         return 0;
      }
	  
	  return 0;    //(added) //sometimes contron may come here as per the compiler so if u wont return it will show a waring
  }

General Rules while dealing with strings:
---strncpy does not terminate a string with '\0'
---fgets takes one line at time until the it gets '\n' or the record length which one comes 1st.
---After getting the record in an array always place '\0' in the end
Because if record lengh is 10 and actual record lengh in file is 5.

fgets will store "xxxxx\n\0" so replace it.

This article has been dead for over six months. Start a new discussion instead.