所以我必须做这样的练习:From STDIN take a string of text of any size, and then change every lowercase character to uppercase and vice versa and print it to a file or STDOUT
。第二部分非常简单。但是现在我怎么能说一个单词,或任何长度的短语?例如,当我这样做时,我总是有一个长度为500左右的缓冲区,但现在它必须输入任何长度。我怎么能这样做?
我必须使用AT&T
语法为32位Linux机器执行此操作。
这是我现在的代码:(不改为大写/小写)
SYSCALL32 = 0x80
READ = 3
WRITE = 4
STDIN = 0
STDOUT = 1
EXIT = 1
BUF_SIZE = 10
.data
TEXT_SIZE: .long 0
BUFOR: .space BUF_SIZE
BUFOR1: .space BUF_SIZE
.globl _start
.text
_start:
reading:
movl $READ, %eax
movl $STDIN, %ebx
movl $BUFOR, %ecx
movl $BUF_SIZE, %edx
int $SYSCALL32
movl %eax, TEXT_SIZE
movl $WRITE, %eax
movl $STDOUT, %ebx
movl $BUFOR, %ecx
movl TEXT_SIZE, %edx
int $SYSCALL32
jmp reading
所以我在这里读取了长度为BUFOR
的{{1}}的输入,但如果输入长度为260字节会怎样?
答案 0 :(得分:1)
对此的简单解决方案是读取块,直到读取的最后一个字节为CR(按下输入):
SYSCALL32 = 0x80
READ = 3
WRITE = 4
STDIN = 0
STDOUT = 1
EXIT = 1
BUF_SIZE = 10
.data
TEXT_SIZE: .long 0
BUFOR: .space BUF_SIZE
BUFOR1: .space BUF_SIZE
.globl _start
.text
_start:
reading:
movl $READ, %eax
movl $STDIN, %ebx
movl $BUFOR, %ecx
movl $BUF_SIZE, %edx
int $SYSCALL32
movl %eax, TEXT_SIZE
; add the code for uppercase <-> lowercase here
movl $WRITE, %eax
movl $STDOUT, %ebx
movl $BUFOR, %ecx
movl TEXT_SIZE, %edx
int $SYSCALL32
movl $BUFOR, %esi ; last byte read = $BUFOR +
addl TEXT_SIZE, %esi ; TEXT_SIZE
mov -1(%esi), %ah ; -1
cmp $0x0a, %ah ; it if's not CR, keep on reading
jnz reading
movl $EXIT, %eax ; otherwise return to OS
int $SYSCALL32
ret
答案 1 :(得分:0)
明智的做法是读取固定大小的缓冲区,处理数据并将其写出来;只要read
返回非零,就继续前进。这实际上不会以任何方式限制输入字符串长度,因为系统会提供一些缓冲区并阻止生成输入的进程写入,直到您的进程读取它为止。
在C中会出现类似的情况:
unsigned char buf[512];
int readsz = 0;
while(readsz = read(0, buf, sizeof(buf))) {
/* ... invert case ... */
write(1, buf, readsz);
}
如果您的分配确实需要一些莫名其妙的理由首先在内存中完全读取整个字符串,那么您必须使用来自libc的malloc
动态分配内存,并且如果缓冲区已完成,则继续realloc
- 循环的每次迭代(您也可以使用sbrk
执行类似的操作,但它更复杂)。那将是这样的:
int capacity = 512;
int size = 0;
int readsz = 0;
char *buf = malloc(capacity);
if(buf==0) abort(); /* not enough memory */
while(readsz = read(0, buf+size, capacity-size)) {
size+=readsz;
if(size==capacity) {
capacity *= 2;
char *nbuf = realloc(buf, capacity);
if(nbuf==0) abort(); /* not enough memory */
buf = nbuf;
}
}
/* now the valid data in buffer is size; do your thing and write it out */
/* ... invert case ... */
write(1, buf, size);
但同样,这是解决问题最愚蠢的方式。使用固定大小的缓冲区。
所以在这里我已经读取了长度为254的
BUFOR
的输入,但如果输入长度为260字节会怎样?
read
将返回前254个字节,并将剩余的字节留在stdin缓冲区中;它将在您下次read
来电时提供。只要read
返回0以外的任何值,就必须循环。当你得到0时,表示标准输入在另一侧关闭,你可以停止阅读并退出。