Примечание. . Следуйте инструкциям Alks в качестве руководства по реализации.

Я хочу создать функцию, которая позволит пользователю вставить каталог, в котором будут сохранены выходные файлы. Мои выходные файлы будут иметь статическое имя, поэтому мне просто нужен путь.

Я хочу прочитать путь от пользователя и добавить его перед именем выходного файла. Так было бы так:

Имя вывода (генерируется другой функцией) outLogFile = "outLogFile.log"

user input = D:\Datasets\some_folder\more_folders

RESULT = D:\Datasets\some_folder\more_folders\outLogFile.log

Как я это делаю, я вставляю имя вывода в temp, использую strcpy для копирования пути к файлу в outLogFile и strcat для добавления temp в outLogFile.

Есть ли более простой способ сделать это? Способ объединить две строки в моем outLogFile без использования временного секретаря? Отдельная команда для копирования строки path_file перед строкой ouLogFile и сохранения ее в outLogFile?

< Сильный > Код:

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

int main ()
{
  char  user_input[100], *path_file,*temp; 
  char *outLogFile = "outLogFile.log";

  printf("Filepath:\n (!Do not inlude filename!)\n");
  gets(user_input);

  path_file = (char*)malloc(strlen(user_input)+1);
  if (user_input[strlen(user_input) - 1]!='\\')
  {
      strcpy(path_file, user_input);
      strcat(path_file, "\\");
  }
  else
  {
      strcpy(path_file, user_input);
  }

  temp = outLogFile;
  strcpy(outLogFile, path_file);
  strcat(outLogFile, temp);

  printf("%s\n%s\n", path_file,outLogFile);
  system("pause");


  return 0;
}

РЕДАКТИРОВАТЬ : я мог бы использовать user_input и path_file для malloc outLogFile и strcpy strcat строки как следует

< Сильный > Код:

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

int main ()
{
  char user_input[100]; 
  char *outLogFile;
  char *path_file = "outLogFile.log";

  printf("Filepath:\n (!Do not inlude filename!)\n");
  fgets(user_input,sizeof(user_input), stdin);

  printf("%c\n",user_input[strlen(user_input) - 1]);
  outLogFile = (char*)malloc(strlen(user_input)+strlen(path_file));

  if (user_input[strlen(user_input) - 1]!='\\')
  {
      strcpy(outLogFile,user_input);
      strcat(outLogFile, "\\");
      strcat(outLogFile,path_file);
  }
  else
  {
      strcpy(outLogFile,user_input);
      strcat(outLogFile,path_file);
  }

  printf("%s",outLogFile);
  system("pause");


  return 0;
}

Однако этот код берет \ n, нажимая кнопку возврата и вставляет его между двумя строками

2
Jimmy_A 24 Апр 2017 в 13:17

2 ответа

Лучший ответ

Для добавления строки к другой строке и сохранения результата в новой строке наиболее гибкий общий подход заключается в использовании динамического распределения памяти следующим образом:

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

int main(void)
{
  char * ps1 = "Hello";
  char * ps2 = " World";

  size_t length_total = strlen(ps1) + strlen(ps2);
  char * ps3 = malloc((length_total + 1) * sizeof *ps3); /* One more for 
                                                            the 0-terminator. */
  if (NULL == ps3)
  {
    perror("malloc() failed");
    exit(EXIT_FAILURE);
  }

  strcpy(ps3, ps1);
  strcat(ps3, ps2);

  /* Use ps3. */
  puts(ps3);

  /* Clean up. */
  free(ps3);

  return EXIT_SUCCESS;
}

В вашем конкретном случае, когда код предоставляет имя файла по умолчанию без пути, а сценарий использования позволяет разрешить префикс имени файла во время выполнения, можно подойти к этому более простым способом, подобным этому.

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

#define LOGFILENAME "some.log"

int main(void)
{
  char logfilepath[PATH_MAX] = LOGFILENAME; /* Just to make sure. */
  char dir[PATH_MAX] = "";

  if (NULL == fgets(dir, sizeof dir, stdin))
  {
    if (ferror(stdin))
    {
      perror("fgets() failed");
      exit(EXIT_FAILURE);
    }
  }

  dir[strcspn(dir, "\n\r")] = 0;

  {
    size_t length_dir = strlen(dir);
    if (length_dir > 0 && '/' != dir[length_dir - 1])
    {
      if (PATH_MAX < length_dir)
      {
        errno = EINVAL;
        perror("'dir' to long");
        exit(EXIT_FAILURE);
      }

      strcat(dir, "/");
      ++length_dir;
    }

    {
      size_t length_total = length_dir + strlen(logfilepath);
      if (PATH_MAX < length_total)
      {
        errno = EINVAL;
        perror("'dir/filename' to long");
        exit(EXIT_FAILURE);
      }
    }
  }

  strcpy(logfilepath, dir);
  strcat(logfilepath, LOGFILENAME);

  /* Use logfilepath, . */
  puts(logfilepath);

  return EXIT_SUCCESS;
}

Чтобы не обманывать это с помощью #define и не использовать третью переменную, перейдите к сдвигу:

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

int main(void)
{
  char logfilepath[PATH_MAX] = "some.log"; 

  {
    char dir[PATH_MAX] = "";

    if (NULL == fgets(dir, sizeof dir, stdin))
    {
      if (ferror(stdin))
      {
        perror("fgets() failed");
        exit(EXIT_FAILURE);
      }
    }

    dir[strcspn(dir, "\n\r")] = 0;

    {
      size_t length_filepath = strlen(logfilepath);
      size_t length_dir = strlen(dir);
      if (length_dir > 0 && '/' != dir[length_dir - 1])
      {
        if (PATH_MAX < length_dir)
        {
          errno = EINVAL;
          perror("'dir' to long");
          exit(EXIT_FAILURE);
        }

        strcat(dir, "/");
        ++length_dir;
      }

      if (PATH_MAX < (length_dir + length_filepath))
      {
        errno = EINVAL;
        perror("'dir/filename' to long");
        exit(EXIT_FAILURE);
      }

      memmove(logfilepath + length_dir, logfilepath, length_filepath + 1);
      memcpy(logfilepath, dir, length_dir);
    }
  }

  /* Use logfilepath, . */
  puts(logfilepath);

  return EXIT_SUCCESS;
}
2
alk 24 Апр 2017 в 13:29

Вы можете использовать sprintf (). Ниже приводится объявление для функции sprintf (). int sprintf (char * str, const char * format, ...)

Например :

sprintf(outLogFile, "%s%s", path_file, outLogFile);

Вы должны заботиться о символе '\ 0' первой строки.

-1
Yasin shihab 24 Апр 2017 в 12:12