Възможно ли е да се отпечата само определена част от C-низ, без да се прави отделен подниз?

Да кажем, че имам следното:

char* string = "Hello, how are you?";

Възможно ли е да се отпечатат само последните 5 байта от този низ? Ами само първите 5 байта? Има ли някакъв вариант на printf, който би позволил това?


person Tim    schedule 15.10.2011    source източник


Отговори (3)


Възможно ли е да се отпечатат само последните 5 байта от този низ?

Да, просто прекарайте указател към предпоследния знак. Можете да определите това чрез string + strlen(string) - 5.

Ами само първите 5 байта?

Използвайте спецификатор на точност: %.5s

#include <stdio.h>
#include <string.h>
char* string = "Hello, how are you?";

int main() {
  /* print  at most the first five characters (safe to use on short strings) */
  printf("(%.5s)\n", string);

  /* print last five characters (dangerous on short strings) */
  printf("(%s)\n", string + strlen(string) - 5);

  int n = 3;
  /* print at most first three characters (safe) */
  printf("(%.*s)\n", n, string);

  /* print last three characters (dangerous on short strings) */
  printf("(%s)\n", string + strlen(string) - n);
  return 0;
}
person Robᵩ    schedule 15.10.2011
comment
@Tim - Добре дошъл. Не забравяйте да гласувате за всички полезни отговори и да приемете отговора, който е решил проблема ви. (P.s. Вслушайте се в съвета в другата публикация - ако вашият низ е твърде кратък, тогава този код няма да успее.) - person Robᵩ; 16.10.2011
comment
Актуализирана примерна програма за справяне с коментарите на @Tim в друг отговор. - person Robᵩ; 16.10.2011
comment
Обърнете внимание, че printf ще спре при първия нулев знак. - person Flimm; 29.04.2014
comment
Удивителен отговор. Знаех, че може да се направи много, но това все пак ме изненада. Благодаря ти много. - person Anton Krug; 07.02.2018

Да, последните пет байта от този низ могат да бъдат направени с:

printf ("%s\n", &(string[strlen (string) - 5]));

Първите пет могат да бъдат направени с:

printf ("%.5s\n", string);

Можете да комбинирате двете, за да получите и поднизове в низа. Думата how може да бъде отпечатана с:

printf ("%.3s\n", &(string[strlen (string) + 7]));

Вие направете трябва да внимавате низът да е достатъчно дълъг, за да работи това. Отпечатването на последните пет знака от низ от един символ ще доведе до недефинирано поведение, тъй като индексът завършва на -4. С други думи, проверете дължината на низа, преди да опитате това.

person paxdiablo    schedule 15.10.2011
comment
Благодаря, много информативно. Възможно ли е да отпечатате първите n байта от низ, ако не знаете какво е n по време на компилация? Кажете, че n е int, мога ли просто да имам printf(%ns, низ); ? Също така, защо е 5.5 вместо само 5 във вашия printf (%5.5s\n, низ); (и по същия начин 3.3 в другия)? - person Tim; 16.10.2011
comment
Тим: да. Вижте спецификатора на формат %*s. По принцип предоставяте int точно преди низа, който указва ширината на низа. - person Jörgen Sigvardsson; 16.10.2011
comment
@Tim: да, Йорген вече каза как да използва нещо като int x = 3; printf ("%.*s, x, "abcde"). Що се отнася до двете числа, това всъщност не е необходимо в този случай, тъй като знаете, че имате достатъчно знаци, но все пак го правя по навик. За низовете това е ефективно минималната и максималната дължина. Ще го махна, защото е излишен тук. - person paxdiablo; 16.10.2011
comment
@JörgenSigvardsson: Мисля, че имахте предвид спецификатора на формат %.*s, а не спецификатора на формат %*s. - person Flimm; 29.04.2014
comment
Обърнете внимание, че printf ще спре при първия нулев знак. - person Flimm; 29.04.2014
comment
@Flimm: Вярно е, че работя върху Windows от доста време, така че е възможно да съм използвал стар Microsoft-изъм. - person Jörgen Sigvardsson; 30.04.2014

Две решения:

Кажете, че е даден предсказуем низ със същата дължина - ще използвам дата като пример и ще поискам да разделя на ЧЧ:ММ:СС.DDDDDDD

char date[14] = "2359591234567";

[1] Четимо изпълнение:

char hh[3] = {0};
char mm[3] = {0};
char ss[3] = {0};
char dec[8] = {0};
strncpy ( hh, date, 2 );
strncpy ( mm, date+2, 2 );
strncpy ( ss, date+4, 2 );
strncpy ( dec, date+6, 7 );

printf("%s:%s:%s.%s\n", hh, mm, ss, dec);

[2] Кратка реализация:

Или:

printf("%.2s:%.2s:%.2s.%.7s\n", date, date+2, date+4, date+6);

or:

printf("%2.2s:%2.2s:%2.2s.%7.7s\n", date, date+2, date+4, date+6);

Трябва да работи.

Вместо printf - можете да използвате sprintf и да копирате в буфер. Също така бих проверил за правилната дължина, за да избегна непредвидимо поведение.

И в двата случая изходът ще бъде:

23:59:59.1234567
person Kapil Vyas    schedule 24.05.2018