Thread: strcat (), argv[], general string trouble

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    5

    strcat (), argv[], general string trouble

    I am trying to scan a directory and match files based on file name (works), then open the matching (text) files and scan the contents (problem).
    I am trying to combine dirent->d_name with "/" and argv[1] to asemble to full path to the file to open it. When I try to strcat(*argv[1], "/") I get:
    "passing argument 1 of 'strcat' makes pointer from integer without a cast".
    Or strcat(argv[1], "/"), I get:
    "passing argument 1 of 'strcat' discards qualifiers from pointer target type".
    I've read a handfull of FAQ's and tutorials, but not finding a solution.

    Code:
    #include <stdio.h>
    #include <sys/types.h>
    #include <dirent.h>
    #include <string.h>
    
    //arg#1 is directory, arg#2 is file match
    int main (const int argc, const char * argv[]){
    	DIR *dp;
    	FILE *infile;
    	struct dirent *ep;
     
    	dp = opendir (argv[1]);
    	if (dp != NULL){
    		char *strcheck;
    		while (ep = readdir (dp)){
    			char *diritem = ep->d_name;
    			strcheck = strstr(diritem, argv[2]);
    			if(strcheck != NULL){
    				char *filepath;
    				filepath = strcat(strcat(argv[1], "/"),ep->d_name);
    				infile = fopen(filepath, "r");
    				if(infile){
    					//code removed
    				}
    			}
    		}
    		(void) closedir (dp);
    	}
    	return 0;
    }
    Side note:
    I thought learning C would be fairly easy, already knowing PHP5, but strings (char arrays) are causing me significant trouble.

  2. #2
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    First of all, I don't think you should be doing this. argv[x] is only guarenteed to be as long as it needs to be to hold the actual string afaik, so I wouldn't strcat() to it. The best idea is to malloc() together a string large enough to move everything to it. That should be the safest and smartest way to handle it.

    As far as the error is concerned, looking at the code, I don't know what the issue is. As long as you're including string.h, it should be working fine, although your usage appears somewhat unorthodox.

    Edit: Wait a second. Why are you declaring argc and argv as const? Especially if you have any plans of editing them at all.
    Last edited by MacGyver; 10-29-2007 at 11:14 PM.

  3. #3
    Registered User
    Join Date
    Oct 2007
    Posts
    5
    I tried before to strcat to a new var, but still had trouble with this part:
    char *path1;
    path1=*argv[1];
    I did not malloc it.
    I'll change it back and try to compile it on Windows instead (of Mac OS X), just to see what happens.
    Then I'll learn how to allocate memory.
    Thanks.

    Oh, why I made argc and argv[] const? Because that's what the tutorial on scanning a directory did, that I started with.
    Last edited by markjoe; 10-29-2007 at 11:25 PM.

  4. #4
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Code:
    char *path1;
    path1=*argv[1];
    Absolutely wrong. You're taking a pointer and assigning it a char instead of an address of a char.

    PHP is probably messing you up with the concept of buffers and properly allocating memory since it hides most of that I believe.

  5. #5
    Registered User
    Join Date
    Oct 2007
    Posts
    5
    So, should that be:
    Code:
    char *path1;
    path1=&argv[1];
    But that would copy the address of argv[1] to path1, right?
    I want to copy the value out to a new variable that I can alter.
    Assigning a char to a pointer... but aren't strings in C just a pointer to the first array element?
    How about this:
    strlen = length of argv[1] + length of "/" + length of filename + 1(for \0)
    Code:
    char path1[strlen];
    path1 = *argv[1];
    ?

    C seems so primitive (no offence to the purists), but it's the only thing that I can run on all 3 platforms I need to deal with.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Like
    Code:
    char newFilename[100];
    strcpy( newFilename, argv[1] );
    strcat( newFilename, "/" );
    strcat( newFilename, ep->d_name );
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Here's an example program:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    /*
    	This program will take a dir as the first arg
    	and a file name as the second arg and then
    	open the file and print it to stdout.
    */
    
    int main(int argc, char *argv[])
    {
    	int c = 0;
    	char szSlash[] = "/";
    	char *szFile = NULL;
    	FILE *f = NULL;
    
    	if(argc < 3)
    	{
    		printf("Usage: &#37;s <path> <file>\n", argv[0]);
    		return 1;
    	}
    	
    	szFile = malloc(strlen(argv[1]) + strlen(szSlash) + strlen(argv[2]) + 1);
    	if(!szFile)
    	{
    		printf("Unable to allocate memory...\n");
    		return 2;
    	}
    	strcpy(szFile, argv[1]);
    	strcat(szFile, szSlash);
    	strcat(szFile, argv[2]);
    	
    	f = fopen(szFile, "r");
    	if(!f)
    	{
    		printf("Unable to open file \"%s\"...\n", szFile);
    		return 3;
    	}
    	while((c = fgetc(f)) != EOF)
    	{
    		putchar(c);
    	}
    	fclose(f);
    	free(szFile);
    
    	return 0;
    }
    And yes, C is primitive, but extremely powerful.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Salem View Post
    Like
    Code:
    #include <limits.h>
    char newFilename[PATH_MAX];
    strcpy( newFilename, argv[1] );
    strcat( newFilename, "/" );
    strcat( newFilename, ep->d_name );
    If you use the above, it will be portable to most machines. As long as there is only one or a few arrays for this, it should be fine to not use malloc()/free() for allocating the memory.

    PATH_MAX is guaranteed to be sufficiently large to hold "any" valid filename [although it is possible construct "valid" filenames or paths that exceed this length if you are using relative paths [e.g. something like "c:\windows\..\windows\..\windows\" could be made "infinitely long" and still valid of sorts- rare and completely solvable by removing the superfluous path content, although that may be a bit difficult to do].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    But PATH_MAX isn't itself a portable concept (it appears nowhere in C99), though I do agree you should use such a constant if one is available.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Oct 2007
    Posts
    5
    If you use the above, it will be portable to most machines. As long as there is only one or a few arrays for this, it should be fine to not use malloc()/free() for allocating the memory.
    This will be used to make a path for any file that matches search criteria, up to 1000 files. Although they only need to be accessed one at a time.

    Regardless of what is which standard, as long as it works on Tru64UNIX, Windows, and Mac, it's good for me.

    Thanks alot for the help fellas!

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by markjoe View Post
    This will be used to make a path for any file that matches search criteria, up to 1000 files. Although they only need to be accessed one at a time.

    Regardless of what is which standard, as long as it works on Tru64UNIX, Windows, and Mac, it's good for me.

    Thanks alot for the help fellas!
    If Mac means MacOS X, rather than older MacOS versions, then I'm fairly sure it will work fine [not quite certain about Tru64UNIX - if that's the exception, just do
    Code:
    #ifndef PATH_MAX
    #define PATH_MAX 1024
    #endif
    or something similar (1024 should be OK for all SANE cases of file/directory structures)].


    You should of course CHECK that the size of the path becomes no longer than the maximum size, whatever way you determine the max size.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User
    Join Date
    Oct 2007
    Posts
    5
    Awesome help! It is working to that level now. It will be a while before I get to test it on the Tru64UNIX, but I'm certain it will go fine with all the info gathered here.
    And, yes, thats Mac OS X, my development environment of choice.
    I went with:
    char newFilename[PATH_MAX];
    instead of:
    szFile = malloc(strlen(argv[1]) + strlen(szSlash) + strlen(argv[2]) + 1);
    However, I think, in principal, malloc is the better choice, because you're not eating any more memory than you actually need. However, yet again, I don't really get memory management yet, and am afraid to mess with it until I understand better.

    Thanks to all, you've made my debut on cprogramming.com forum a pleasant one!
    Now I'm off to get that next big contract with NASA, haha.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. RicBot
    By John_ in forum C++ Programming
    Replies: 8
    Last Post: 06-13-2006, 06:52 PM
  2. string trouble
    By howdytest in forum C++ Programming
    Replies: 16
    Last Post: 12-27-2004, 09:45 PM
  3. can anyone see anything wrong with this code
    By occ0708 in forum C++ Programming
    Replies: 6
    Last Post: 12-07-2004, 12:47 PM
  4. Linked List Help
    By CJ7Mudrover in forum C Programming
    Replies: 9
    Last Post: 03-10-2004, 10:33 PM
  5. Removing 'strcat' ed string.
    By Unregistered in forum C Programming
    Replies: 3
    Last Post: 11-14-2001, 12:09 AM