Вы делаете это очень неловко для себя. Вы хорошо справляетесь с использованием fgets()
для обработки ввода, но вам не нужно маркировать строку ввода для разделения имени файла и расширения. Вместо этого (и вместо использования strchr()
) используйте strrchr()
, чтобы найти последний '.'
во входной строке. Таким образом, если у вас есть имя файла, похожее на "somefile.version.ext"
, вы можете правильно разделить имя файла на имя "somefile.version"
, а расширение "ext"
.
strrchr
предоставит указатель на финал '.'
на входе (или NULL
, если '.'
не включено). Там у вас есть адрес массива, заполненный fgets()
, и у вас есть адрес последнего '.'
в этой строке, все, что вам нужно сделать, это вычесть указатель, возвращенный strrchr()
, и массив, заполненный fgets()
определить количество символов для копирования. Тогда простой вызов memcpy
- это все, что вам нужно для выполнения копирования, а затем nul-terminate новой строки в этой точке.
Например, если вы читаете с fgets()
в buf
, а затем хотите разделить buf
на fname
с именем файла и ext
с расширением, все что вам нужно:
char buf[MAXC], fname[MAXC], ext[MAXC], *p;
...
if ((p = strrchr (buf, '.'))) { /* get pointer to last '.' */
memcpy (fname, buf, p - buf); /* copy chars up to last '.' */
fname[p-buf] = 0; /* nul-terminate fname */
strcpy (ext, p+1); /* copy extension */
}
Обратите внимание, что, поскольку у вас есть указатель к окончательному '.'
все, что вам нужно сделать, это strcpy (ext, p+1);
, чтобы скопировать расширение.
Короткий пример, который ставит его целиком и обрабатывает случай, когда в имени файла нет '.'
: :
#include <stdio.h>
#include <string.h>
#define MAXC 1024 /* if you need a constract, #define one (or moare) */
int main (void) {
char buf[MAXC], fname[MAXC], ext[MAXC], *p;
fputs ("enter filename: ", stdout); /* prompt for filename */
if (!fgets(buf, MAXC, stdin)) { /* read/validate filename */
fputs ("(user canceled input)\n", stderr);
return 1;
}
buf[strcspn (buf, "\n")] = 0; /* trim \n from end of buf */
if ((p = strrchr (buf, '.'))) { /* get pointer to last '.' */
memcpy (fname, buf, p - buf); /* copy chars up to last '.' */
fname[p-buf] = 0; /* nul-terminate fname */
strcpy (ext, p+1); /* copy extension */
}
else { /* no '.' in buf */
strcpy (fname, buf); /* copy bur to fname */
*ext = 0; /* make ext empty-string */
}
printf ("filename : %s\n", fname);
if (*ext)
printf ("extension : %s\n", ext);
}
( примечание: вы должны проверить, что fname
не является пустой строкой , чтобы обрабатывать точечные файлы, et c, .somefile
- это вам осталось)
Пример использования / Вывод
$ ./bin/filename_ext
enter filename: somefile.ext
filename : somefile
extension : ext
Что если в имени файла более одного '.'
?
$ ./bin/filename_ext
enter filename: somefile.version.ext
filename : somefile.version
extension : ext
Что, если их нет?
$ ./bin/filename_ext
enter filename: somefilenoext
filename : somefilenoext
Это гораздо более простой способ приблизиться к разделению, чем токенизация северо-восток Посмотрите вещи и дайте мне знать, если у вас есть вопросы.