簡體   English   中英

如何更改字符串中的每個字符但不更改 C 中的標點符號?

[英]How do I change each char in a string but not change punctuations in C?

我有一個任務是創建一個程序,該程序將字符串中的每個字符轉換為在命令行中輸入的一組數字。 示例:如果用戶在命令行輸入 1 然后輸入abc, def那么程序應該將字符串轉換為bcd, efg

我已經編寫了程序,但我不知道如何讓程序不轉換標點符號。

該程序當前轉換abc, def並打印bcdefg 它需要打印bcd, efg並包含標點字符而不轉換它們。

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

int main(int argc, string argv[]) //user enter number at cmd prompt

{
    string key = argv[1]; //store user entered number
    int k = atoi(argv[1]); //only accept consecutive digits
    if (argc != 2 || k == 0) 
    {    
        printf("Usage: ./caesar key\n"); /*show error if user enters non-consecutive digits*/
        return 1;
    }
    string original = get_string("Plaintext: "); /* prompt user for message to spin*/

    for (int i = 0, n = strlen(original); i < n; i++)  /* get string length and loop char change*/            
        if (isalnum(original[i])) /* only convert alphanumeric character*/                    
            printf("%c", original[i] + k); /* print and convert character by number entered at prompt*/

    printf("\n");
    return 0;
}

您只輸出您正在轉換的字符(那些在isalnum集中的字符)。 您還需要 output 未轉換的字符。 例如:

    char cipher = original[i] ;
    if( isalnum( original[i] )
    {
        cipher += k ;
    }

    printf( "%c", cipher ) ;

然而,所描述的算法在幾個方面仍然存在嚴重缺陷,但尚不清楚是分配有缺陷(在這種情況下,這不是您的問題)還是您對分配的描述不准確。

更實用的解決方案可能如下所示:

#include <ctype.h>

char caesar( char x, int key )
{
    const char alphabet[] = {'a','b','c','d','e','f','g','h',
                             'i','j','k','l','m','n','o','p',
                             'q','r','s','t','u','v','w','x',
                             'y','z',
                             '0','1','2','3','4','5','6','7','8','9'};

    char cipher = x  ;

    for( int i = 0;
         cipher == x && i < sizeof( alphabet );
         i++ )
    {
        if( alphabet[i] == tolower( x ) )
        {
            cipher = alphabet[(i + key) % sizeof( alphabet )] ;
            if( isupper( x ) )
            {
                cipher = toupper( cipher ) ;
            }
        }
    }

    return cipher ;
}

那么您的 output 循環將是:

for( int i = 0; original[i] != '\0' ); i++)
{
    printf("%c", ceasar( original[i], k ) ) ;
}

您當前正在執行的操作僅在字符 + k是字母數字時打印,否則不打印。 您真正想要做的只是添加k如果它是字母數字。 通過一點 boolean 邏輯和數學,我們可以完全避免 if 語句。

printf("%c", original[i] + (k * !!isalnum(original[i])));

如果isalnum返回真, !! 將使結果值為 1(如果為真,它可以返回非零值;如果為真,則邏輯上的雙重否定將使其為 1,如果為假,則為 0)。 所以現在我們添加k如果它是字母數字,否則不添加任何內容,並以任何一種方式打印字符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM