正确打印输出

时间:2014-09-25 12:25:54

标签: c

我正在运行

ls -l | myprogram

基本上我想以正确的方式打印输出。当我们独立ls -l时,可以有很多行。每行包含8个元素。所以我想以ls -l给出输出的方式打印它,但跳过顶部的两个元素(总数)。例如,ls -l给了我们

total 3
-rwx------ 1 cre university 8381 Sep 24 21:04 a.out
drwx------ 5 cre university 4096 Sep 16 19:36 file2
-rwx------ 1 cre university 8499 Sep 25 00:50 file1

我需要ls -l | myprogram

-rwx------ 1 cre university 8381 Sep 24 21:04 a.out
drwx------ 5 cre university 4096 Sep 16 19:36 file2
-rwx------ 1 cre university 8499 Sep 25 00:50 file1

这是我到目前为止。它只是在一行中打印所有元素。 不知道如何在8个元素的行中实现该部分。之后我想比较文件的大小。请帮助,初学者在这里!

4 个答案:

答案 0 :(得分:0)

也许你可以找到" \ n \ n"在您的输入流中,这是空行。从那里,您将获得输入流的其余内容。

答案 1 :(得分:0)

在do while循环中,您可以尝试添加" \ n"到printf语句,如下所示:

do {    
    result=scanf("%s",string);
    printf("%s\n", string);
} while (result!=EOF);

然而,do / while并不安全 - 请参阅下面的代码。

如果您需要跳过"总X"你可以用以下两种方式之一做到这一点: 知道它是第一行并跳过它或者进行字符串比较"总X"然后跳过它。鉴于它会在那里,我可能会选择后一种选择 - 当然,除非很快就会改变。为了完全安全,正则表达式可能是最安全的,但实施时间更长。

这是一个例子。注意我把它从do / while改为do。这是因为你需要在使用之前检查结果是否= EOF,而上面的do / while并没有给你一个机会去做。一会儿更安全。

 while (EOF != (result = scanf("%s", string))) {
    // skip line containing "total X"
    if (strncmp(result, "total ", sizeof("total ")) == 0) {
        continue;
    }
    printf("%s\n", string);
 }

免责声明 - 我还没有编译过这个,所以不太确定sizeof(" total")在语法上是否正确,但这个想法应该是。

希望这会有所帮助。

答案 2 :(得分:0)

虽然

  

“ls -l | tail -n +2”   很好的答案。如果你想用你的代码做,只需检查行的开头

...
 while (NULL != fgets(string, sizeof(string), stdin)) { 
    if (strncmp(string, "total", strlen("total")) == 0) {
        continue;
    }
    printf("%s ", string);
 }
...

答案 3 :(得分:0)

您可能希望跳过某些与模式匹配的行。使用能够很好地表达正则表达式的语言(例如:awk,perl,ruby,python等)可以做得更好。

您可以读取每一行,但匹配并跳过某些容易检测到模式的行,例如以" total"开头的行,空行和"。"和" .."特殊目录,

linebuffer[1024];
while( fgets(linbuffer,sizeof(linebuffer),stdin) ) {
    if( strlen(linebuffer) < 2 ) continue; //short lines
    if( strncmp(linebuffer,"total",strlen("total")==0 ) continue; //line begins with "total"
    //do you want to skip ".", ".."?
    if( strcmp(linebuffer+strlen(linebuffer)-2,".\n")==0 ) continue; //skip ".", ".."
    printf("%s",linebuffer); //or use puts
}

另一种方法是打开目录,读取它并解码文件信息(参见stat(2)),这将跳过&#34; total&#34;相当方便,

int res;
struct stat statbuf;
char pathname[1024];
DIR* dir;
struct dirent  *dp=NULL;
char* fname;

if( !(dir=opendir(dname)) ) {
    int ec=errno;
    printf("error:-1:cannot opendir %s\n",dname,ec);
    return(-1);
}
while ((dp = readdir(dir)) != NULL) {
    //printf("file: %s\n",dp->d_name); fflush(stdout);
    if( strcmp(dp->d_name,".")==0 ) continue;
    if( strcmp(dp->d_name,"..")==0 ) continue;
    fname=dp->d_name;
    //call stat(2) here on the file,
    sprintf(pathname,"%s/%s",dname,dp->d_name);
    if( (res=stat(dname, &statbuf)) == -1) {
        int ec=errno;
        printf("error:-1:cannot stat %s (%d)\n",pathname,ec);
        return(-1);
    }
    //printf("dirwatch:check (%s)\n",pathname);
    print_fileinfo(&statbuf,dp->d_name); //left as an exercise for the poster
}
closedir(dir);

您需要解码并打印stat(2)信息,

int
print_fileinfo(stat* statbuf, char* name)
{
    //decode rwx bits for owner, group, and other
    //lookup owner and group names
    //file size is part of statbuf
    //file type (regular, directory, et al) is part of statbuf
}

您需要查看stat(2)手册页,但这里有一些有用的值,宏,

   All of these system calls return a stat structure, which contains the following fields:

       struct stat {
           dev_t     st_dev;     /* ID of device containing file */
           ino_t     st_ino;     /* inode number */
           mode_t    st_mode;    /* protection */
           nlink_t   st_nlink;   /* number of hard links */
           uid_t     st_uid;     /* user ID of owner */
           gid_t     st_gid;     /* group ID of owner */
           dev_t     st_rdev;    /* device ID (if special file) */
           off_t     st_size;    /* total size, in bytes */
           blksize_t st_blksize; /* blocksize for file system I/O */
           blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
           time_t    st_atime;   /* time of last access */
           time_t    st_mtime;   /* time of last modification */
           time_t    st_ctime;   /* time of last status change */
       };

   The following POSIX macros are defined to check the file type using the st_mode field:

       S_ISREG(m)  is it a regular file?

       S_ISDIR(m)  directory?

       S_ISCHR(m)  character device?

       S_ISBLK(m)  block device?

       S_ISFIFO(m) FIFO (named pipe)?

       S_ISLNK(m)  symbolic link?  (Not in POSIX.1-1996.)

       S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)

   The following flags are defined for the st_mode field:

       S_IFMT     0170000   bit mask for the file type bit fields
       S_IFSOCK   0140000   socket
       S_IFLNK    0120000   symbolic link
       S_IFREG    0100000   regular file
       S_IFBLK    0060000   block device
       S_IFDIR    0040000   directory
       S_IFCHR    0020000   character device
       S_IFIFO    0010000   FIFO
       S_ISUID    0004000   set UID bit
       S_ISGID    0002000   set-group-ID bit (see below)
       S_ISVTX    0001000   sticky bit (see below)
       S_IRWXU    00700     mask for file owner permissions
       S_IRUSR    00400     owner has read permission
       S_IWUSR    00200     owner has write permission
       S_IXUSR    00100     owner has execute permission
       S_IRWXG    00070     mask for group permissions
       S_IRGRP    00040     group has read permission
       S_IWGRP    00020     group has write permission
       S_IXGRP    00010     group has execute permission
       S_IRWXO    00007     mask for permissions for others (not in group)
       S_IROTH    00004     others have read permission
       S_IWOTH    00002     others have write permission
       S_IXOTH    00001     others have execute permission