提问人:Determinante 提问时间:10/24/2023 最后编辑:OkaDeterminante 更新时间:10/24/2023 访问量:37
KandR2 Entab 程序说明
KandR2 Entab program clarification
问:
这是 KandR2 书中的练习 5-11。
练习 5-11。修改程序 “entab” 和 “detab”(在第 1 章中作为练习编写)以接受制表位列表作为参数。如果没有参数,请使用默认选项卡设置。
我只是不明白下面的代码在做什么。这不是我的代码;我已经准备好了自己的代码,但比较下面代码的输出,我怀疑我的解决方案。 下面的第一个代码输出完全相同的输入,当我在 vscode 的终端中输入选项卡时,它不会缩小 entab 程序应该做的选项卡。
是不是程序在 vscode 中的终端上运行导致输出不正确?因为编写此代码的人/她使用.txt文件来测试它获得正确的输出。
这是解决方案的链接 https://clc-wiki.net/wiki/K%26R2_solutions:Chapter_5:Exercise_11#Solution_by_anonymous 请检查链接以获得清晰的图片。 这里有什么问题?
''' `
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#define DEFAULT_TAB_STOP 8 // length of default tab stop. For entab, this needs to be the tab stop size of the shell/tool that displays the contents since tabs are in the output.
#define MAX_TABS 1000 // max supported custom tabs
void shellsort(int v[], int n);
int main(int argc, char *argv[])
{
int c, i = 0, j, k, col = 0, spaces = 0; // i is index in tabs, j is the next custom/default tab stop, k is the distance to the natural tab stops to see if a tab will fit
int tabs[MAX_TABS];
while (--argc > 0) // get all arguments and store them in tabs
{
if (i >= MAX_TABS)
return 1; // too many arguments
else if (isdigit(**++argv)) // only allow arguments that start with a digit
tabs[i++] = atoi(*argv); // gets all valid digits in string and turns it into an int
else
return 2; // argument started with non-digit
}
int n = 0; // this is used as a multiplier to fill tabs up with the default tab stop if no custom tab stops were provided or not enough of them were provided to fill up tabs
if (i > 0) // if i > 0, then custom tab stops were provided as an argument
{
shellsort(tabs, i); // puts ints in numerical order
n = tabs[i - 1]; // gets the largest value in tabs
n += DEFAULT_TAB_STOP - (n % DEFAULT_TAB_STOP); // moves n to the next default tab stop
n /= DEFAULT_TAB_STOP; // gets the base of the number to use in the next while loop
}
while (i < MAX_TABS) // adds the rest of the default tabs to tabs array
tabs[i++] = n++ * DEFAULT_TAB_STOP; // uses base n to get value of next tab stop after the last largest custom one. Appends to it the end of tabs
i = 0; // resets index
while ((c = getchar()) != EOF)
{
if (c != ' ') // if the char is not a space, all saved spaces need to be processed before it is printed
{
while (spaces > 0) // this allows the below logic to only think about things one iteration at a time
{
k = DEFAULT_TAB_STOP - (col % DEFAULT_TAB_STOP); // find the next default tab stop
while (tabs[i] <= col && i < MAX_TABS) // get the next custom/default tab stop
i++;
if (i < MAX_TABS) // but only if not out of bounds of array
j = tabs[i] - col;
if (k <= j && spaces - k >= 0) // if the natural tab is less than the custom tab and there are enough spaces, substitute a tab for the spaces
{
putchar('\t');
col += k; // updates col position
spaces -= k; // updates spaces used
}
else // if natural tab is greater than custom one, fill in the spaces until the custom tab stop is met. Keep track of col position and spaces left
{
while (spaces > 0 && j-- > 0)
{
putchar(' ');
col++;
spaces--;
}
}
}
}
switch (c)
{
case ' ': // don't print the spaces, but keep track of the number of them (they are processed above)
spaces++;
break;
case '\n': // reset the col and tabs index and print it
col = 0;
i = 0;
putchar(c);
break;
case '\t': // find the next custom tab, subtract the number of spaces from it to current col and add that to spaces. These spaces will be processed the next iteration
while (tabs[i] <= col && i < MAX_TABS)
i++;
if (i < MAX_TABS)
j = tabs[i] - col;
spaces += j;
break;
default: // all other chars are printed and col position is incremented by one
putchar(c);
col++;
break;
}
}
return 0;
}
// sort v[0]...v[n-1] into increasing order
void shellsort(int v[], int n)
{
int gap, i, j, temp;
for (gap = n / 2; gap > 0; gap /= 2)
for (i = gap; i < n; i++)
for (j = i - gap; j >= 0 && v[j] > v[j + gap]; j -= gap)
{
temp = v[j];
v[j] = v[j + gap];
v[j + gap] = temp;
}
}` '''
这是一个示例测试,将文本文件与 entab 一起使用,以查看选项卡宽度 3 是否正确输出。
cat pipe.txt | ./entab 3 6 9 12 15 18 21 24 27 30 33
请检查上面给出的链接中的pipe.txt,因为它在此处显示直接导致格式问题。
这是我得到的结果:
PS C:\Users\nivek\OneDrive\Desktop\Ccode\entabcompare1> .\a.exe 5 6 9
|
|
我已经输入了 5 个空格来到达自定义制表位 5,我在这里只收到输入,但实际上,根据原始的 entab 程序,光标应该在第 8 个位置,因为默认的 shell/系统制表位是 8。
预期结果是:
`PS C:\Users\nivek\OneDrive\Desktop\Ccode\entab> .\a.exe 5 6 9`
|
|
我不知道这是怎么回事,.txt文件在做什么?
答: 暂无答案
评论