Linux應用編程IO基礎

Linux應用編程基本IO操作

  • 一、main 函數
    • 1、main 函數寫法之無傳參
    • 2、main 函數寫法之有傳參
  • 二、open 打開文件
  • 三、write 寫文件
  • 四、read 讀文件
  • 五、close 關閉文件
  • 六、 lseek
  • 七、 返回錯誤處理與 errno
    • 7.1 strerror 函數
    • 7.2 perror 函數
  • 八、 exit、_exit、_Exit
    • 8.1_exit()和_Exit()函數
    • 8.2 exit()函數
  • 九、 格式化 I/O
    • 9.1 格式化輸出
      • printf()函數
      • fprintf()函數
      • dprintf()函數
      • sprintf()函數
      • snprintf()函數
    • 9.2 格式化輸入
      • scanf()函數
      • fscanf()函數
      • sscanf()函數

一、main 函數

1、main 函數寫法之無傳參

int main(void) {/* 代碼 */
}

2、main 函數寫法之有傳參

int main(int argc, char **argv) {/* 代碼 */
}

二、open 打開文件

在 Linux 系統中要操作一個文件,需要先打開該文件,得到文件描述符,然后再對文件進行相應的讀寫操作(或其他操作),最后在關閉該文件;open 函數用于打開文件,當然除了打開已經存在的文件之外,還可以創建一個新的文件,函數原型如下所示:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

open 函數使用示例
(1)使用 open 函數打開一個已經存在的文件(例如當前目錄下的 app.c 文件),使用只讀方式打開:

int fd = open("./app.c", O_RDONLY)
if (-1 == fd)
return fd;

(2)使用 open 函數打開一個已經存在的文件(例如當前目錄下的 app.c 文件),使用可讀可寫方式打開:

int fd = open("./app.c", O_RDWR)
if (-1 == fd)
return fd;

(3)使用 open 函數打開一個指定的文件(譬如/home/dengtao/hello),使用可讀可寫方式,如果該文件是
一個符號鏈接文件,則不對其進行解引用,直接返回錯誤

int fd = open("/home/dengtao/hello", O_RDWR | O_NOFOLLOW);
if (-1 == fd)
return fd;

(4)使用 open 函數打開一個指定的文件(譬如/home/dengtao/hello),如果該文件不存在則創建該文件,
創建該文件時,將文件權限設置如下:
文件所屬者擁有讀、寫、執行權限;
同組用戶與其他用戶只有讀權限。
使用可讀可寫方式打開:

int fd = open("/home/dengtao/hello", O_RDWR | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH);
if (-1 == fd)
return fd;

三、write 寫文件

調用 write 函數可向打開的文件寫入數據,其函數原型如下所示(可通過"man 2 write"查看):

#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

四、read 讀文件

調用 read 函數可從打開的文件中讀取數據,其函數原型如下所示(可通過"man 2 read"查看):

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

五、close 關閉文件

可調用 close 函數關閉一個已經打開的文件,其函數原型如下所示(可通過"man 2 close"查看):

#include <unistd.h>
int close(int fd);

六、 lseek

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);

使用示例:
(1)將讀寫位置移動到文件開頭處:

off_t off = lseek(fd, 0, SEEK_SET);
if (-1 == off)
return -1;

(2)將讀寫位置移動到文件末尾:

off_t off = lseek(fd, 0, SEEK_END);
if (-1 == off)
return -1;

(3)將讀寫位置移動到偏移文件開頭 100 個字節處:

off_t off = lseek(fd, 100, SEEK_SET);
if (-1 == off)
return -1;

(4)獲取當前讀寫位置偏移量:

off_t off = lseek(fd, 0, SEEK_CUR);
if (-1 == off)
return -1;

七、 返回錯誤處理與 errno

7.1 strerror 函數

前面給大家說到了 errno 變量,但是 errno 僅僅只是一個錯誤編號,對于開發者來說,即使拿到了 errno也不知道錯誤為何?還需要對比源碼中對此編號的錯誤定義,可以說非常不友好,這里介紹一個 C 庫函數strerror(),該函數可以將對應的 errno 轉換成適合我們查看的字符串信息,其函數原型如下所示(可通過"man 3 strerror"命令查看,注意此函數是 C 庫函數,并不是系統調用):

#include <string.h>
char *strerror(int errnum);

接下來我們測試下,測試代碼如下:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main(void)
{
int fd;
/* 打開文件 */
fd = open("./test_file", O_RDONLY);
if (-1 == fd) {
printf("Error: %s\n", strerror(errno));
return -1;
}
close(fd);
return 0;
}

7.2 perror 函數

除了 strerror 函數之外,我們還可以使用 perror 函數來查看錯誤信息,一般用的最多的還是這個函數,調用此函數不需要傳入 errno,函數內部會自己去獲取 errno 變量的值,調用此函數會直接將錯誤提示字符串打印出來,而不是返回字符串,除此之外還可以在輸出的錯誤提示字符串之前加入自己的打印信息,函數原型如下所示(可通過"man 3 perror"命令查看):

#include <stdio.h>
void perror(const char *s);

接下來我們進行測試,測試代碼如下所示:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
int fd;
/* 打開文件 */
fd = open("./test_file", O_RDONLY);
if (-1 == fd) {
perror("open error");
return -1;
}
close(fd);
return 0;
}

八、 exit、_exit、_Exit

8.1_exit()和_Exit()函數

main 函數中使用 return 后返回,return 執行后把控制權交給調用函數,結束該進程。調用_exit()函數會清除其使用的內存空間,并銷毀其在內核中的各種數據結構,關閉進程的所有文件描述符,并結束進程、將控制權交給操作系統。_exit()函數原型如下所示:

#include <unistd.h>
void _exit(int status);

調用函數需要傳入 status 狀態標志,0 表示正常結束、若為其它值則表示程序執行過程中檢測到有錯誤發生。使用示例如下:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
int fd;
/* 打開文件 */
fd = open("./test_file", O_RDONLY);
if (-1 == fd) {
perror("open error");
_exit(-1);
}
close(fd);
_exit(0); }

_Exit()函數原型如下所示:

#include <stdlib.h>
void _Exit(int status);

_exit()和_Exit()兩者等價,用法作用是一樣的,這里就不再講了,需要注意的是這 2 個函數都是系統調用。

8.2 exit()函數

exit()函數_exit()函數都是用來終止進程的,exit()是一個標準 C 庫函數,而_exit()和_Exit()是系統調用。執行 exit()會執行一些清理工作,最后調用_exit()函數。exit()函數原型如下:

#include <stdlib.h>
void exit(int status);

九、 格式化 I/O

在前面編寫的測試代碼中,會經常使用到庫函數 printf()用于輸出程序中的打印信息,printf()函數可將格式化數據寫入到標準輸出,所以通常稱為格式化輸出。除了 printf()之外,格式化輸出還包括:fprintf()、dprintf()、sprintf()、snprintf()這 4 個庫函數。
除了格式化輸出之外,自然也有格式化輸入,從標準輸入中獲取格式化數據,格式化輸入包括:scanf()、fscanf()、sscanf()這三個庫函數,那么本小節將向大家介紹 C 語言庫函數的格式化 I/O。

9.1 格式化輸出

C 庫函數提供了 5 個格式化輸出函數,包括:printf()、fprintf()、dprintf()、sprintf()、snprintf(),其函數定義如下所示:

#include <stdio.h>
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int dprintf(int fd, const char *format, ...);
int sprintf(char *buf, const char *format, ...);
int snprintf(char *buf, size_t size, const char *format, ...);

printf()函數

前面章節內容編寫的示例代碼中多次使用了該函數,用于將程序中的字符串信息輸出顯示到終端(也就是標準輸出),相信各位讀者學習 C 語言時肯定用過該函數,它是一個可變參函數,除了一個固定參數 format外,后面還可攜帶 0 個或多個參數。
函數調用成功返回打印輸出的字符數;失敗將返回一個負值!

打印“Hello World”:

printf("Hello World!\n");

打印數字 5:

printf("%d\n", 5);

fprintf()函數

fprintf()可將格式化數據寫入到由 FILE 指針指定的文件中,譬如將字符串“Hello World”寫入到標準錯誤:

fprintf(stderr, "Hello World!\n");

向標準錯誤寫入數字 5:

fprintf(stderr, "%d\n", 5);

函數調用成功返回寫入到文件中的字符數;失敗將返回一個負值!

dprintf()函數

dprintf()可將格式化數據寫入到由文件描述符 fd 指定的文件中,譬如將字符串“Hello World”寫入到標準錯誤:

dprintf(STDERR_FILENO, "Hello World!\n");

向標準錯誤寫入數字 5:

dprintf(STDERR_FILENO, "%d\n", 5);

函數調用成功返回寫入到文件中的字符數;失敗將返回一個負值!

sprintf()函數

sprintf()函數將格式化數據存儲在由參數 buf 所指定的緩沖區中,譬如將字符串“Hello World”存放在緩沖區中:

char buf[100];
sprintf(buf, "Hello World!\n");

當然這種用法并沒有意義,事實上,我們一般會使用這個函數進行格式化轉換,并將轉換后的字符串存放在緩沖區中,譬如將數字 100 轉換為字符串"100",將轉換后得到的字符串存放在 buf 中:

char buf[20] = {0};
sprintf(buf, "%d", 100);

sprintf()函數會在字符串尾端自動加上一個字符串終止字符’\0’。

snprintf()函數

sprintf()函數可能會發生緩沖區溢出的問題,存在安全隱患,為了解決這個問題,引入了 snprintf()函數;在該函數中,使用參數 size 顯式的指定緩沖區的大小,如果寫入到緩沖區的字節數大于參數 size 指定的大小,超出的部分將會被丟棄!如果緩沖區空間足夠大,snprintf()函數就會返回寫入到緩沖區的字符數,與sprintf()函數相同,也會在字符串末尾自動添加終止字符’\0’。

9.2 格式化輸入

C 庫函數提供了 3 個格式化輸入函數,包括:scanf()、fscanf()、sscanf(),其函數定義如下所示:

#include <stdio.h>
int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);

scanf()函數

int a, b, c;
scanf("%d %d %d", &a, &b, &c);

fscanf()函數

int a, b, c;
fscanf(stdin, "%d %d %d", &a, &b, &c);

sscanf()函數

char *str = "5454 hello";
char buf[10];
int a;
sscanf(str, "%d %s", &a, buf);

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/42006.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/42006.shtml
英文地址,請注明出處:http://en.pswp.cn/web/42006.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

零基礎自學爬蟲技術該從哪里入手?

零基礎學習Python并不一定是困難的&#xff0c;這主要取決于個人的學習方法、投入的時間以及學習目標的設定。Python是一門相對容易入門的編程語言&#xff0c;它有著簡潔的語法、豐富的庫和廣泛的應用領域&#xff08;如數據分析、Web開發、人工智能等&#xff09;&#xff0c…

大模型知識問答: 文本分塊要點總結

節前&#xff0c;我們組織了一場算法崗技術&面試討論會&#xff0c;邀請了一些互聯網大廠朋友、今年參加社招和校招面試的同學。 針對大模型技術趨勢、算法項目落地經驗分享、新手如何入門算法崗、該如何準備面試攻略、面試常考點等熱門話題進行了深入的討論。 總結鏈接如…

C++ 信號量和鎖的區別

網上關于信號量和鎖的區別&#xff0c;寫的比較官方晦澀難懂&#xff0c;對于這個知識點吸收難&#xff0c;通過示例&#xff0c;我們看到信號量&#xff0c;可以控制同一時刻的線程數量&#xff0c;就算同時開啟很多線程&#xff0c;依然可以的達到線程數可控 #include <i…

初識c++(命名空間,缺省參數,函數重載)

一、命名空間 1、namespace的意義 在C/C中&#xff0c;變量、函數和后面要學到的類都是大量存在的&#xff0c;這些變量、函數和類的名稱將都存在于全 局作用域中&#xff0c;可能會導致很多沖突。使用命名空間的目的是對標識符的名稱進行本地化&#xff0c;以避免命名 沖突…

GEE代碼實例教程詳解:MODIS土地覆蓋分類與面積計算

簡介 在本篇博客中&#xff0c;我們將使用Google Earth Engine (GEE) 對MODIS土地覆蓋數據進行分析。通過MODIS/061/MCD12Q1數據集&#xff0c;我們可以識別不同的土地覆蓋類型&#xff0c;并計算每種類型的總面積。 背景知識 MODIS MCD12Q1數據集 MODIS/061/MCD12Q1是NASA…

每天一個數據分析題(四百十五)- 線性回歸模型

線性回歸模型中誤差項的數學期望為 A. 0 B. 1 C. 2 D. 3 數據分析認證考試介紹&#xff1a;點擊進入 題目來源于CDA模擬題庫 點擊此處獲取答案 數據分析專項練習題庫 內容涵蓋Python&#xff0c;SQL&#xff0c;統計學&#xff0c;數據分析理論&#xff0c;深度學習&am…

世界商用飛機機型大全-使用Java抓取FlightAware后的答案

目錄 前言 一、數據說明 1、實時航班飛機機型數據 2、網頁結構分析 二、使用Java進行信息抓取 1、定義頁面PageVO對象 2、爬取屬性定義 3、啟動信息抓取組件 三、成果分析 1、商業飛行的飛機機型的種類 2、飛機種類排名前十名 3、航班數排名后十名 4、看中國國產大飛…

【網絡安全】一文帶你了解什么是【網絡劫持】

網絡劫持&#xff08;Network Hijacking&#xff09;是一種網絡攻擊&#xff0c;攻擊者通過非法手段劫持網絡通信&#xff0c;導致合法用戶的數據流被攔截、篡改或重定向到攻擊者控制的系統。這種攻擊可以在各種網絡層面上進行&#xff0c;包括域名系統&#xff08;DNS&#xf…

你真的會信息收集嘛,4k字滲透測試信息收集10大技巧

前言 在滲透測試中&#xff0c;信息收集是非常關鍵的一步&#xff0c;它為后續的漏洞發現和利用提供了重要的基礎。以下是非常詳細的信息收集方式&#xff1a; 一、被動信息收集 被動信息收集是指在不與目標系統直接交互的情況下&#xff0c;通過公開渠道獲取目標系統的相關…

基于51單片機的四路搶答器Protues仿真設計

一、設計背景 近年來隨著科技的飛速發展&#xff0c;單片機的應用正在不斷的走向深入。本文闡述了基于51單片機的八路搶答器設計。本設計中&#xff0c;51單片機充當了核心控制器的角色&#xff0c;通過IO口與各個功能模塊相連接。按鍵模塊負責檢測參與者的搶答動作&#xff0c…

線程交互現象

線程交互現象 小明對自家的狗子有個規定,就是在狗狗還沒吃完的時候,可以繼續給他加飯 不好的解決方式 狗狗感覺一千年沒吃飯了,狼吞虎咽起來,最后飯只剩下最后一點點,吃飯線程中使用while循環判斷是否是1,如果是1那么就一直循環,知道加飯又重新回到了起點,這雖然是狗狗…

GEE代碼實例教程詳解:湖泊面積分析

GEE代碼實例教程詳解&#xff1a;湖泊面積分析 完整代碼 // 定義研究區域的坐標點 var coordinates [[42.000552219688586, 38.18969302118053],[43.868228000938586, 38.18969302118053],[43.868228000938586, 39.209978258633186],[42.000552219688586, 39.20997825863318…

C++ --> 類和對象(一)

歡迎來到我的Blog&#xff0c;點擊關注哦&#x1f495; 前言 前面講到了C的入門需要學習的知識&#xff0c;是為了后面更好的學習。學習是不斷深入的&#xff0c;內容是不斷復雜的。篤定信心。 一、面向對象編程(OOP)和面向過程編程(POP)的認識 面向過程編程&#xff08;Proc…

力扣-貪心算法4

406.根據身高重建隊列 406. 根據身高重建隊列 題目 假設有打亂順序的一群人站成一個隊列&#xff0c;數組 people 表示隊列中一些人的屬性&#xff08;不一定按順序&#xff09;。每個 people[i] [hi, ki] 表示第 i 個人的身高為 hi &#xff0c;前面 正好 有 ki 個身高大于或…

MyBatis的簡介與使用

Mybatis JDBC操作數據庫的缺點 存在大量的冗余代碼。手工創建 Connection、Statement 等&#xff0c;效率低下。手工將結果集封裝成實體對象。查詢效率低&#xff0c;沒有對數據訪問進行優化。 Mybatis框架 簡介 MyBatis 本是 apache 的一個開源項目 iBatis, 2010年這個項目由…

imx6ull/linux應用編程學習(14) MQTT基礎知識

什么是mqtt&#xff1f; 與HTTP 協議一樣&#xff0c; MQTT 協議也是應用層協議&#xff0c;工作在 TCP/IP 四層模型中的最上層&#xff08;應用層&#xff09;&#xff0c;構建于 TCP/IP協議上。 MQTT 最大優點在于&#xff0c;可以以極少的代碼和有限的帶寬&#xff0c;為連接…

網絡資源模板--Android Studio 外賣點餐App

目錄 一、項目演示 二、項目測試環境 三、項目詳情 四、完整的項目源碼 原創外賣點餐&#xff1a;基于Android studio 實現外賣(點)訂餐系統 非原創奶茶點餐&#xff1a;網絡資源模板--基于 Android Studio 實現的奶茶點餐App報告 一、項目演示 網絡資源模板--基于Android …

在AvaotaA1全志T527開發板上使用AvaotaOS 部署 Docker 服務

Docker 是一個開源的應用容器引擎&#xff0c;讓開發者可以打包他們的應用以及依賴包到一個可移植的鏡像中&#xff0c;然后發布到任何流行的 Linux或Windows操作系統的機器上&#xff0c;也可以實現虛擬化。容器是完全使用沙箱機制&#xff0c;相互之間不會有任何接口。 準備…

dolphinscheduler-springboot集成

springboot集成dolphinscheduler 說明 為了避免對DolphinScheduler產生過度依賴&#xff0c;實踐中通常不會全面采用其內置的所有任務節點類型。相反&#xff0c;會選擇性地利用DolphinScheduler的HTTP任務節點功能&#xff0c;以此作為工作流執行管理的橋梁&#xff0c;對接…

信息技術課上的紀律秘訣:營造有序學習環境

信息技術課是學生們探索數字世界的樂園&#xff0c;但同時也是課堂紀律管理的挑戰場。電腦、網絡、游戲等元素可能分散學生的注意力&#xff0c;影響學習效果。本文將分享一些有效的策略&#xff0c;幫助教師在信息技術課上維持課堂紀律&#xff0c;確保教學活動順利進行。 制…