<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # C 編程,第 2 部分:文本輸入和輸出 > 原文:[Processes, Part 1: Introduction](https://github.com/angrave/SystemProgramming/wiki/Processes%2C-Part-1%3A-Introduction) > 校驗:[_stund](https://github.com/hqiwen) > 自豪地采用[谷歌翻譯](https://translate.google.cn/) ## 打印到流 ### 如何將字符串,整數,字符打印到標準輸出流? 使用`printf`。第一個參數是格式字符串,其中包含要打印的數據的占位符。通用格式說明符是`%s`將參數視為 c 字符串指針,保持打印所有字符,直到達到 NULL 字符; `%d`將參數打印為整數; `%p`將參數打印為內存地址。 一個簡單的例子如下所示: ```c char *name = ... ; int score = ...; printf("Hello %s, your result is %d\n", name, score); printf("Debug: The string and int are stored at: %p and %p\n", name, &score ); // name已經是一個字符串指針,指向字符串的開頭第一個字節的地址。 // 我們需要用“&”操作符來獲取整數變量score的地址。 ``` 默認情況下,為了提高性能,`printf`實際上不會寫出任何內容(通過調用 write),直到其緩沖區已滿或打印出換行符。 ### 我怎么能打印字符串和單個字符? 使用`puts( name );`和`putchar( c )`,其中 name 是指向 C 字符串的指針,c 只是`char` ### 如何打印到其他文件流? 使用`fprintf( _file_ , "Hello %s, score: %d", name, score);`其中 _file_ 是預定義的'stdout''stderr'或`fopen`或`fdopen`返回的 FILE 指針 ### 我可以使用文件描述符嗎? 是!只需使用`dprintf(int fd, char* format_string, ...);`只記得可以緩沖流,因此您需要確保將數據寫入文件描述符。 ### 如何將數據打印到 C 字符串中? 使用`sprintf`或更好`snprintf`。 ```c char result[200]; int len = snprintf(result, sizeof(result), "%s:%d", name, score); ``` ~~snprintf 返回寫入的字符數,不包括終止字節。在上面的例子中,這最多為 199。~~snprintf 返回有足夠的空間寫入字符串的長度,不包括末尾NULL字節。 ```c char x[5]; int size = snprintf(x, 5, "%s%s%s", "12", "34", "56"); // writes "1234" + null printf("%d\n", size); // output 6 ``` 來源: ![this StackOverflow post](https://stackoverflow.com/questions/12746885/why-use-asprintfand) 和 手冊頁。 ### 如果我真的希望`printf`在沒有換行符的情況下調用`write`怎么辦? 使用`fflush( FILE* inp )`。將寫入文件的內容。如果我想寫沒有換行的“Hello World”,我可以像這樣寫。 ```c int main(){ fprintf(stdout, "Hello World"); fflush(stdout); return 0; } ``` ### `perror`如何幫助? 假設您有一個失敗的函數調用(因為您檢查了手冊頁,它是一個失敗的返回碼)。 `perror(const char* message)`會將錯誤的英文版本打印到 stderr ```c int main(){ int ret = open("IDoNotExist.txt", O_RDONLY); if(ret < 0){ perror("Opening IDoNotExist:"); } //... return 0; } ``` ## 解析輸入 ### 如何從字符串中解析數字? 使用`long int strtol(const char *nptr, char **endptr, int base);`或`long long int strtoll(const char *nptr, char **endptr, int base);`。 這些函數的作用是將指針指向您的字符串`*nptr`和`base`(即二進制,八進制,十進制,十六進制等)和可選指針`endptr`,并返回一個解析的 int。 ```c int main(){ const char *num = "1A2436"; char* endptr; long int parsed = strtol(num, &endptr, 16); return 0; } ``` 但要小心!錯誤處理有點棘手,因為該函數不會返回錯誤代碼。如果你傳入一個會返回0的字符串而不是一個數字,這意味著你不能區別出一個合格的“0”和一個不合格的字符串。查看參考手冊頁去獲得更多的關于strtol的不合法行為和超出邊界的值。一個安全的替代是使用`sscanf`(并且檢查返回值)。 ```c int main(){ const char *input = "0"; // or "!##@" or "" char* endptr; long int parsed = strtol(input, &endptr, 10); if(parsed == 0){ // 不管輸入的字符串是一個合格的10進制數還是真的是0 } return 0; } ``` ### 如何使用`scanf`將輸入解析為參數? 使用`scanf`(或`fscanf`或`sscanf`)分別從默認輸入流,任意文件流或 C 字符串獲取輸入。檢查返回值以查看解析了多少項是個好主意。 `scanf`函數需要有效的指針。傳遞不正確的指針值是常見的錯誤來源。例如, ```c int *data = (int *) malloc(sizeof(int)); char *line = "v 10"; char type; // 好習慣:確保scanf解析了line并讀取了兩個值 int ok = 2 == sscanf(line, "%c %d", &type, &data); // pointer error ``` 我們想將字符值寫入 c,將整數值寫入 malloc 內存。但是我們傳遞了數據指針的地址,而不是指針指向的地址!所以`sscanf`會改變指針本身。即,指針現在將指向地址 10,因此該代碼稍后將失敗,例如當調用 free(數據)時。 ### 如何阻止 scanf 導致緩沖區溢出? 以下代碼假定 scanf 不會將超過 10 個字符(包括終止字節)讀入緩沖區。 ```c char buffer[10]; scanf("%s",buffer); ``` 您可以包含一個可選的整數來指定排除終止字節的字符數: ```c char buffer[10]; scanf("%9s", buffer); // 讀取至多9個字符從輸入(第十個字節是留給終止字節的) ``` ### 為什么`gets`很危險?我應該用什么呢? 以下代碼容易受到緩沖區溢出的影響。它假定或信任輸入行不超過 10 個字符,包括終止字節。 ```c char buf[10]; gets(buf); // 請記住數組名代表著數組的第一個字節 ``` `gets`在 C99 標準中已棄用,已從最新的 C 標準(C11)中刪除。程序應使用`fgets`或`getline`代替。 每個都分別具有以下結構: ```c char *fgets (char *str, int num, FILE *stream); ssize_t getline(char **lineptr, size_t *n, FILE *stream); ``` 這是一種簡單,安全的讀取單行的方法。超過 9 個字符的行將被截斷: ```c char buffer[10]; char *result = fgets(buffer, sizeof(buffer), stdin); ``` 如果出現錯誤或文件結束,則結果為 NULL。注意,與`gets`不同,`fgets`將換行符復制到緩沖區中,您可能要將其丟棄 - ```c if (!result) { return; /* no data - don't read the buffer contents */} int i = strlen(buffer) - 1; if (buffer[i] == '\n') buffer[i] = '\0'; ``` ### 我該如何使用`getline`? `getline`的一個優點是將在足夠大小的堆上自動(重新)分配緩沖區。 ```c // ssize_t getline(char **lineptr, size_t *n, FILE *stream); /* 初始化buffer和size的值,它們會被getline所改變 */ char *buffer = NULL; size_t size = 0; ssize_t chars = getline(&buffer, &size, stdin); // 如果有換行符,就丟棄換行符 if (chars > 0 && buffer[chars-1] == '\n') buffer[chars-1] = '\0'; // 讀取另外一行 // 存在的緩沖區會被重復使用,如果有必要它會被釋放并分配一個更大的緩沖區 chars = getline(&buffer, &size, stdin); // 最后,不要忘了釋放緩沖區內存 free(buffer); ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看