Используйте mkdir -p "${a%/*}";
перед иконкой.
Обратите внимание, что вы используете потенциально опасную конструкцию for
, когда в именах файлов есть пробелы, см. http://porkmail.org/era/unix/award.html .
Этот код не будет работать просто потому, что строка:
num = "123056";
изменится num
указывает от выделенной памяти (и p
остается указателем на эту память, поэтому они больше не в том же месте) на то, что, скорее всего, является постоянной памятью. Вам не разрешено изменять память, принадлежащую строковым литералам, это поведение undefined.
Вам понадобится следующее:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char *num = malloc (100); // do not cast malloc return value.
char *p = num;
strcpy (num, "123056"); // populate existing block with string.
p = p + 3; // set pointer to where '0' is.
*p = '4'; // and change it to '4'.
printf ("%s\n", num ); // output it.
return 0;
}
Прежде всего, когда вы делаете:
num = "123056";
Вы не копируете строку «123056» в область кучи, выделенную с помощью malloc ()
. В C присвоение указателю char *
значения строкового литерала эквивалентно установке его как константы, то есть идентично:
char str[] = "123056";
Итак, то, что вы только что сделали, это то, что вы отказались от своей единственной ссылка на 100-байтовую область кучи, выделенную функцией malloc ()
, поэтому ваш последующий код не печатает правильное значение; ' p
' по-прежнему указывает на область кучи, выделенную malloc ()
(поскольку num
указывал на нее во время присваивания), но num
больше не работает.
Я предполагаю, что вы действительно намеревались сделать скопировать строку «123056» в эту область кучи. Вот как это сделать:
strcpy(num, "123056");
Хотя это лучше по разным причинам:
strncpy(num, "123056", 100 - 1); /* leave room for \0 (null) terminator */
Если бы вы только что сделали:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *num = malloc(100);
char *p = num;
strncpy(num, "123056", 100 - 1);
p = p + 3;
*p = '4';
printf("%s\n", num);
return 0;
}
Вы бы получили правильный результат:
123456
Вы можете сократить эту операцию:
p = p + 3;
*p = '4';
... и избегайте повторения указателя, определяя его следующим образом:
*(p + 3) = '4';
Несколько других примечаний:
Хотя обычная стилистическая практика, приведение возвращаемого значения malloc ()
к ] (char *)
не требуется. Преобразование и выравнивание типа void *
гарантируется языком C.
ВСЕГДА проверяйте возвращаемое значение malloc ()
. Это будет NULL, если выделение кучи не удалось (т. Е. У вас закончилась память), и в этот момент ваша программа должна завершиться.
В зависимости от реализации, область памяти, выделенная функцией malloc ()
, в определенных ситуациях может содержать устаревший мусор. Всегда полезно обнулить его после выделения:
memset (num, 0, 100);
Никогда не забывайте освободить ()
свою кучу! В этом случае программа завершится, а ОС очистит ваш мусор, но если вы не войдете в привычку, мгновенно возникнут утечки памяти.
Итак, вот «лучшая» версия:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *num, *p;
/*
* Don't take 1-byte chars for granted - good habit to get into.
*/
num = malloc(sizeof(char) * 100);
if(num == NULL)
exit(1);
memset(num, 0, sizeof(char) * 100);
p = num;
strncpy(num, "123056", 100 - 1);
*(p + 3) = '4';
printf("%s\n", num);
free(num);
return 0;
}
Помимо проблемы с * p, на которую указали другие, у вас также есть проблемы с использованием памяти. У вас есть буфер размером 100 байт с неизвестным содержимым. У вас есть еще один буфер размером 7 байт, содержащий строку «123056» и нулевой терминатор. Вы делаете следующее:
Таким образом, вы не печатаете тот же буфер, что и вы модификация.
Ну, вы знаете, что p - это указатель. Он хранит адрес char '0'. Если вы присвоите p значение «4». В качестве адреса потребуется цифра 4. Однако адрес «4» недопустим. Вы можете использовать оператор '*', чтобы получить значение, адрес которого хранится в p.