2015-03-02 3 views
0

Мой код внизу. Я пытаюсь взять две строки и изменить их в соответствии с редактируемой стенограммой, которую я получаю. Я написал свой код, но я не понимаю, почему я получаю такой странный вывод. Моя цель состоит в том, чтобы сначала сохранить значения двух строк, а затем сделать их в 2D-массив, но я не выполняю первую часть этой цели. Вот проблема:Выравнивание символа weird output

Создать функцию, которая соответствует следующему:

входа: редактировать расшифровку и 2 оригинальных строки (3 строки)

Выход: 2 d массив А, содержащий два выравнивания сообщения Редактировать

Пример:

s1 = “vintner” 
s2 = “writers” 
trans = “RIMDMDMMI” 

R означает "заменить" я означает "вставить" M означает "матч" D означает "удалить" Ответ:

alignment={“v_intner_”, 
“wri_t_ers”}; //return a 2d array 

Прототип функции:

char** getAlignment(char* s1, char* s2, char* s3); 

Вот мой код ниже:

char TestS1[] = "vintner"; 
char TestS2[] = "writers"; 
char TestS3[] = "RIMDMDMMI"; 
char twoDarray[2][10]; 

char** getAlignment(char* s1, char* s2, char* s3){ 
    char transTemp[n]; 
    char s1Temp[n]; 
    char s2Temp[n]; 
    char sOne[n]; 
    char sTwo[n]; 
    strcpy(sOne, s1); 
    strcpy(sTwo, s2); 
    int jj; 
    strcpy(transTemp, s3); 
    int kk; 
    for(jj=0, kk=0; jj<n, kk<n; jj++, kk++){ 

     if(transTemp[jj]=='R') 
     { 
      s1Temp[kk] = sOne[jj]; 
      s2Temp[kk] = sTwo[jj]; 
     } 

     if(transTemp[jj]=='I'){ 
      s1Temp[kk] = '_'; 
      s1Temp[kk+1] = sOne[jj]; 
      s2Temp[kk] = sTwo[jj]; 
      kk++; 
     } 

     if(transTemp[jj] == 'M'){ 
      s1Temp[kk] = sOne[jj]; 
      s2Temp[kk] = sTwo[jj]; 
     } 

     if(transTemp[jj] == 'D'){ 
      s2Temp[kk] = '_'; 
      s2Temp[kk+1] = sTwo[jj]; 
      s1Temp[kk] = sOne[jj]; 
      kk++; 
     } 


    } 

    printf("\ns1Temp = %s\n", s1Temp); 
    printf("\ns2Temp = %s\n", s2Temp); 


    return 0; 
} 

main() 
{ 
printf("The new method returns: ", getAlignment(TestS1,TestS2,TestS3)); 
return 0; 
} 
+1

Нет спецификатор формата здесь: 'Е ("Новый метод возвращает:", getAlignment (TestS1, TestS2, TestS3));' –

+0

Да, спасибо за указание на это. Однако мне все равно, что случилось с этим заявлением printf. Я просто хотел вызвать функцию. Значения, на которых я сосредоточен, распечатываются в функции. –

+0

Вы пытаетесь вернуть 'int' с функцией, предназначенной для возврата' char ** ' –

ответ

1

Ваш вопрос действительно имеет две части: как я могу вернуть две строки? И почему я не получаю желаемый результат?

Строки в C - массивы символов. Вы редко возвращаете строки. Чаще всего передать массив символов в функцию вместе с максимальной длиной и заполнить этот массив. Функции в <string.h> делают это. Хорошая модель дизайна, на мой взгляд, snprintf: она заполняет буфер, не заботится о переполнении, гарантирует, что результат корректно завершен с нулем и возвращает количество написанных символов, если бы буфер был достаточно большим. Это последнее свойство позволяет передать длину null (и в качестве специального примера указатель NULL), чтобы узнать, сколько символов вам нужно, и распределить память по мере необходимости.

Так прототип для функции может выглядеть следующим образом:

int getAlignment(char *res1, char *res2, size_t n, 
    const char* s1, const char* s2, const char* trans); 

Кроме того, что получившиеся строки могут быть разной длины в вашем случае.

Вы также можете вернуть строки, но вам придется либо вернуть новую память, выделенную malloc в кучу, что означает, что код клиента должен явно указывать free или указатели на уже существующую память. Конечно, вы можете вернуть только одну строку.

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

Что касается второго вопроса: ваша главная проблема заключается в том, что у вас есть три строки - две строки источника и одна строка перевода, но сохраняются только два индекса. Все строки пересекаются независимо; синхронизация между индексами строк отсутствует.

Вы добавляете к строкам результата, когда идете. Строка «вождения» - это строка трансляции, поэтому вы должны проходить только с основным контуром.

Следует отметить, что вам не нужно делать копии исходных строк. Это не только неотложно, но и опасно, потому что strcpy может переполнять буферы. Уход за переполнением с помощью strncpy может привести к потере входных строк.

Я обновил свою реализацию:

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

#define N 10 

struct Result { 
    char res1[N]; 
    char res2[N]; 
}; 

struct Result getAlignment(const char* s1, const char* s2, const char* trans) 
{ 
    struct Result res; 

    int j1 = 0;    // index into s1 
    int j2 = 0;    // index into s2 
    int n = N - 1;   // leave 1 char for null terminator 

    while (*trans) { 

     if (*trans == 'R') { 
      if (j1 < n) res.res1[j1++] = *s1++; 
      if (j2 < n) res.res2[j2++] = *s2++; 
     } 

     if (*trans == 'I'){ 
      if (j1 < n) res.res1[j1++] = '_'; 
      if (j1 < n) res.res1[j1++] = *s1++; 
      if (j2 < n) res.res2[j2++] = *s2++; 
     } 

     if (*trans == 'M') { 
      if (j1 < n) res.res1[j1++] = *s1++; 
      if (j2 < n) res.res2[j2++] = *s2++; 
     } 

     if (*trans == 'D') { 
      if (j1 < n) res.res1[j1++] = *s1++; 
      if (j2 < n) res.res2[j2++] = '_'; 
      if (j2 < n) res.res2[j2++] = *s2++; 
     } 

     trans++; 
    } 

    // null-terminate strings 
    res.res1[j1] = '\0'; 
    res.res2[j2] = '\0'; 

    return res; 
} 

int main() 
{ 
    char *str1 = "vintner"; 
    char *str2 = "writers"; 
    char *trans = "RIMDMDMMI"; 

    struct Result res = getAlignment(str1, str2, trans); 

    printf("%s\n%s\n\n", res.res1, res.res2); 

    return 0; 
} 

Things отметить:

  • Строка перевода проходится с помощью указателя, который сохраняет индекс.

  • Строки результата добавляются только в том случае, если достаточно места. Вы можете изменить N на 5 и посмотреть, как строки результата усекаются после 4 символов, тем самым теряя информацию, но предотвращая переполнение буфера.

  • Оба индекса строки результата и указатели исходной строки увеличиваются по мере продвижения.

  • Исходные строки считываются только с. (Вот почему копирование не имеет смысла.) Таким образом, в сигнатуре функции они должны быть const char *.