Как объединить все параметры командной строки вместе и распечатать полученное значение?

У меня возникли проблемы при попытке выяснить, как объединить путь к файлу со строками. Пользователь вводит строки в командной строке следующим образом:

    StringLabMain.exe Mary had a little lamb 1234

Предполагается распечатать что-то вроде этого:

    Concatenated arguments: d:\Documents and Settings\labadmin\My Documents\Visual Studio 2012\Projects\test\debug\StringLabMain.exeMaryhadalittlelamb1234

но мой код распечатывает это:

    Concatenated arguments: StringLabMain.exeMaryhadalittlelamb1234

Вот мой код (я не понимаю, как работает конкатенация, чтобы включить путь к файлу со строками):

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

      int i;

      for (i = 0; i < argc; i++)
      {
         printf("%s", argv[i]);

      }
      return 0;
    }

Я надеюсь, что я объяснил это ясно.

2 ответа

Решение

Во-первых, если ваша единственная цель - напечатать каталог и объединенные аргументы, то вам просто нужно распечатать текущий каталог перед основным циклом. Это может быть сделано с помощью getcwd().

#include <stdio.h>
#include <unistd.h>

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

  int i;
  printf("%s", getcwd(0,0));
  for (i = 0; i < argc; i++)
  {
     printf("%s", argv[i]);
  }
  return 0;
}

Но для более общих целей я действительно рекомендую вам использовать stracat(), который объединяет строки. Таким образом, вы должны объявить "строку" (используя char *) с текущим рабочим каталогом, а затем объединить аргументы. Это будет сделано так:

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

int main(int argc, char *argv[])
{
  char* toPrint;
  int i;
  toPrint = getcwd(0,0);
  for (i = 0; i < argc; i++)
    strcat (toPrint, argv[i]);
  printf("%s\n",toPrint);
  return 0;
} 

Я надеюсь, что знаю, это понятно.

Следующий код демонстрирует, как использовать strcat() для создания строки всех элементов argv[]:

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

int main(int argc, char *argv[])
   {
   int     i;
   size_t  outputSize = 1;
   char   *output     = NULL;

   /* Allocate a buffer large enough to hold the string termination character. */
   output=malloc(outputSize);
   if(!output)
      {
      fprintf(stderr, "malloc() failed.\n");
      goto CLEANUP;
      }
   *output = '\0';

   /* Iterate argv[] elements. */
   for(i = 0; i < argc; i++)
      {
      char *tmp;

      /* Increase the size of the output buffer to hold this argv[] element. */
      outputSize += strlen(argv[i]);
      tmp=realloc(output, outputSize);
      if(!tmp)
         {
         fprintf(stderr, "realloc() failed.\n");
         goto CLEANUP;
         }
      output=tmp;          

      /* Concatinate this argv[] element to the output string. */
      strcat(output, argv[i]);
      }

   /* Print the result. */
   printf("%s\n", output);

CLEANUP:

   if(output)
      free(output);

   return 0;
   } 

В Linux вы также можете указать путь к текущему рабочему каталогу, например так:

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

int main(int argc, char *argv[])
   {
   int     i;
   size_t  outputSize;
   char   *output     = NULL;

   output=getcwd(NULL,0);
   if(!output)
      {
      fprintf(stderr, "getcwd() failed.\n");
      goto CLEANUP;
      }
   outputSize = strlen(output) + 1;

   for(i = 0; i < argc; i++)
      {
      char *tmp;

      outputSize += strlen(argv[i]);
      tmp=realloc(output, outputSize);
      if(!tmp)
         {
         fprintf(stderr, "realloc() failed.\n");
         goto CLEANUP;
         }
      output=tmp;          

      strcat(output, argv[i]);
      }

   printf("%s\n", output);

CLEANUP:

   if(output)
      free(output);

   return 0;
   }  

Приведенный выше пример специфичен для Linux из-за расширения Linux для getcwd(). Страница man getcwd для Linux гласит:

В качестве расширения стандарта POSIX.1-2001, Linux (libc4, libc5, glibc) getcwd() динамически распределяет буфер с помощью malloc(3), если buf равен NULL. В этом случае выделенный буфер имеет размер длины, если размер не равен нулю, когда buf выделяется настолько большим, насколько это необходимо. Вызывающий должен освободить (3) возвращенный буфер.

По-видимому, _getcwd() работает так же в MS Windows. MSDN сообщает о _getcwd():

Функция _getcwd получает полный путь к текущему рабочему каталогу для диска по умолчанию и сохраняет его в буфере. Целочисленный аргумент maxlen указывает максимальную длину пути. Ошибка возникает, если длина пути (включая завершающий нулевой символ) превышает maxlen. Аргумент буфера может быть NULL; буфер, по крайней мере, размера maxlen (больше только в случае необходимости) автоматически выделяется, используя malloc, для хранения пути. Этот буфер позже можно освободить, вызвав free и передав ему возвращаемое значение _getcwd (указатель на выделенный буфер).

Таким образом, возможно, следующий (непроверенный) код подойдет для среды MS Windows:

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

int main(int argc, char *argv[])
   {
   int     i;
   size_t  outputSize;
   char   *output     = NULL;

   output=_getcwd(NULL,0);
   if(!output)
      {
      fprintf(stderr, "_getcwd() failed.\n");
      goto CLEANUP;
      }
   outputSize = strlen(output) + 1;

   for(i = 0; i < argc; i++)
      {
      char *tmp;

      outputSize += strlen(argv[i]);
      tmp=realloc(output, outputSize);
      if(!tmp)
         {
         fprintf(stderr, "realloc() failed.\n");
         goto CLEANUP;
         }
      output=tmp;          

      strcat(output, argv[i]);
      }

   printf("%s\n", output);

CLEANUP:

   if(output)
      free(output);

   return 0;
   }  
Другие вопросы по тегам